AI mascot · ChatGPT + Seedance

Make an AI mascot your ads can run every week

An AI mascot is one weird, recurring character that fronts every ad you run. Design it in ChatGPT, lock it with a reference sheet, then have Seedance swap it into a UGC clip. Same face every week is the whole point.

Crumb, an AI-generated croissant mascot in round wire glasses, white tube socks and red high-topsPrompt 1: design
Reference sheet for Crumb the croissant: front, three-quarter and walking side profilePrompt 2: reference sheet

Step 1: design the character in ChatGPT

One prompt: a name, a body, clothes, one trait you can see, and 'shoot it like a real photo'. That last line is what makes it weird instead of cartoon.

Pick something with a silhouette you can read at thumbnail size, not a person. A croissant, a pigeon, a plant. Here is the exact prompt for Crumb, a bakery mascot, and what came back.

Prompt 1 · paste into ChatGPT

Design an original mascot for a neighborhood bakery's TikTok ads. His name is Crumb.

Crumb is a butter croissant the size of a house cat, standing upright on two skinny legs in white tube socks and red high-top sneakers. Two short stubby arms. Small round wire glasses. Deadpan, slightly tired expression, like he has worked the 5am shift for 30 years. Realistic flaky golden pastry texture with a few crumbs falling off.

Shoot it like a real photo, not a cartoon or 3D render: 50mm lens, soft daylight, shallow depth of field. Plain warm-grey studio background. Full body, centered, square image.

Crumb, an AI-generated croissant mascot in round wire glasses, white tube socks and red high-tops
Crumb, for a neighborhood bakery
Gloria, an AI-generated pigeon mascot in a beige trench coat with pearl earrings and a handbag
Gloria, for a budgeting app
Monty, an AI-generated monstera plant mascot in a terracotta pot on legs in corduroys and loafers
Monty, for a houseplant delivery brand

Crumb, Gloria and Monty are the first result from the prompt shown, made with OpenAI's gpt-image-2.5 through the Images API. Paste the same prompt into ChatGPT and you get the same kind of result. The Gloria and Monty prompts are under their sheets below. The turnaround and the profile further down are what that sheet is for: one look from every angle, then the same look in every post.

Step 2: lock it with a character reference sheet

Same chat, one follow-up: three views on one background. The sheet, not the original image, is what every video job gets from now on.

Prompt 2 · same chat

Turn this character into a character reference sheet I can reuse for video. Three views side by side on one plain warm-grey background, same lighting and same scale in every view:

1. Front view, head and upper body, looking straight at the camera.

2. Three-quarter view, full body, turned 45 degrees to the left.

3. Full body side profile, mid-stride, walking to the right.

Keep every detail identical to the image: shape, colours, textures, clothes, accessories and proportions. Photoreal, like the original. No text, no labels, no logos, no grid lines.

Reference sheet for Crumb the croissant: front, three-quarter and walking side profile
Crumb: front, three-quarter, full body
Reference sheet for Gloria the pigeon: front, three-quarter and walking side profile
Gloria: front, three-quarter, full body
Gloria's design prompt

Design an original mascot for a budgeting app's TikTok and Reels ads. Her name is Gloria.

Gloria is a city pigeon the height of a person, standing upright like a human. Beige trench coat, belted. Pearl earrings. A tiny leather handbag hooked on one wing. Grey feathers with the green-purple sheen on her neck, orange eyes, one eyebrow-feather raised like she has just seen your card statement. Judgmental but classy.

Shoot it like a real photo, not a cartoon or 3D render: 50mm lens, soft daylight, shallow depth of field. Plain warm-grey studio background. Full body, centered, square image.

Reference sheet for Monty the monstera: front, three-quarter and walking side profile
Monty: front, three-quarter, full body
Monty's design prompt

Design an original mascot for a houseplant delivery brand's TikTok and Reels ads. His name is Monty.

Monty is a monstera plant in a terracotta pot, standing on two long human-like legs in brown corduroy trousers and polished brown loafers. Big glossy split leaves on top, one leaf drooping over like a fringe. No face, no eyes: all the personality is in the posture. He stands with one hip cocked, slightly too confident.

Shoot it like a real photo, not a cartoon or 3D render: 50mm lens, soft daylight, shallow depth of field. Plain warm-grey studio background. Full body, centered, square image.

The call behind Crumb's sheet: the design image goes in, the sheet comes back in 26 seconds.

Terminal showing the OpenAI Images API edit request that turned Crumb into a reference sheet, and its HTTP 200 response
The reference sheet request and its response.
Character reference sheet of a man with a tall curled grey wig, lavender shirt, striped tie, grey shorts, striped socks and a black briefcase, shown from the front, back and both sides, plus four head shots
Take the sheet further: four full-body views, then four heads. The wig, the shirt, the tie, the shorts and the briefcase stay put.

Step 3: have Seedance make the UGC base clip

Seedance refuses reference videos with real human faces, unless the clip came out of Seedance on your own account in the last 30 days. So the base clip is a Seedance clip, not phone footage.

Write the clip like a creator would shoot it: selfie angle, one line, one take. The person in it is a stand-in. Step 4 replaces them.

Base clip prompt

Vertical selfie UGC video. A woman in her 30s in a sunny kitchen holds a paper bakery bag up to the phone camera, takes a bite of a croissant and says: "Okay. This croissant is ridiculous." Handheld phone camera, natural light, one take, no music.

Seedance 2.0 · BytePlus ModelArk · create task
curl -s https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ARK_API_KEY" \
  -d '{
    "model": "dreamina-seedance-2-0-260128",
    "content": [
      { "type": "text", "text": "Vertical selfie UGC video. A woman in her 30s in a sunny kitchen holds a paper bakery bag up to the phone camera, takes a bite of a croissant and says: \"Okay. This croissant is ridiculous.\" Handheld phone camera, natural light, one take, no music." }
    ],
    "ratio": "9:16",
    "resolution": "720p",
    "duration": 8,
    "generate_audio": true,
    "watermark": false
  }'
# -> { "id": "cgt-..." }

Step 4: swap the character into the clip

Send the sheet as a reference image and the untouched base clip as a reference video, and tell Seedance who replaces whom. Motion, framing and the line stay; the person becomes Crumb.

curl · create the swap, then poll
curl -s https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ARK_API_KEY" \
  -d '{
    "model": "dreamina-seedance-2-0-260128",
    "content": [
      { "type": "text", "text": "Replace the woman in Video 1 with the croissant character in Image 1. Keep the camera move, framing, timing and the line she says from Video 1. Keep the character identical to Image 1." },
      { "type": "image_url", "image_url": { "url": "https://your-cdn/crumb-sheet.jpg" }, "role": "reference_image" },
      { "type": "video_url", "video_url": { "url": "https://your-cdn/base-clip.mp4" }, "role": "reference_video" }
    ],
    "ratio": "adaptive",
    "duration": -1,
    "resolution": "720p",
    "generate_audio": true,
    "watermark": false
  }'

# Poll until "status" is "succeeded", then download content.video_url (it expires in 24 hours).
curl -s https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks/$TASK_ID \
  -H "Authorization: Bearer $ARK_API_KEY"
TypeScript · create and wait
const ARK = 'https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks'

type Status = 'queued' | 'running' | 'succeeded' | 'failed' | 'cancelled' | 'expired'
interface ArkTask {
  id: string
  status: Status
  content?: { video_url?: string }
  error?: { code: string; message: string } | null
}

const headers = () => {
  const key = process.env.ARK_API_KEY
  if (!key) throw new Error('ARK_API_KEY is not set')
  return { 'Content-Type': 'application/json', Authorization: `Bearer ${key}` }
}

/** Swap the character from a reference sheet into a Seedance base clip. Returns the task id. */
export async function createSwap(sheetUrl: string, baseClipUrl: string): Promise<string> {
  const res = await fetch(ARK, {
    method: 'POST',
    headers: headers(),
    body: JSON.stringify({
      model: 'dreamina-seedance-2-0-260128',
      content: [
        { type: 'text', text: "Replace the woman in Video 1 with the croissant character in Image 1. Keep the camera move, framing, timing and the line she says from Video 1. Keep the character identical to Image 1." },
        { type: 'image_url', image_url: { url: sheetUrl }, role: 'reference_image' },
        { type: 'video_url', video_url: { url: baseClipUrl }, role: 'reference_video' },
      ],
      ratio: 'adaptive',
      duration: -1,
      resolution: '720p',
      generate_audio: true,
      watermark: false,
    }),
  })
  if (!res.ok) throw new Error(`create failed ${res.status}: ${await res.text()}`)
  const { id } = (await res.json()) as { id?: string }
  if (!id) throw new Error('create returned no task id')
  return id
}

/** Poll every 10 seconds for up to 15 minutes. */
export async function waitForVideo(id: string): Promise<string> {
  const deadline = Date.now() + 15 * 60_000
  while (Date.now() < deadline) {
    const res = await fetch(`${ARK}/${id}`, { headers: headers() })
    if (!res.ok) throw new Error(`poll failed ${res.status}: ${await res.text()}`)
    const task = (await res.json()) as ArkTask
    if (task.status === 'succeeded') {
      // A success with no URL is still a failure.
      if (!task.content?.video_url) throw new Error('succeeded without a video_url')
      return task.content.video_url // expires in 24 hours: copy it to your own storage now
    }
    if (task.status !== 'queued' && task.status !== 'running') {
      throw new Error(`task ${task.status}: ${task.error?.code ?? ''} ${task.error?.message ?? ''}`)
    }
    await new Promise((r) => setTimeout(r, 10_000))
  }
  throw new Error(`task ${id} timed out`)
}

What comes back

The task returns one MP4 at the length of the base clip. The camera move, the framing, the timing and the line are the base clip's. The person is gone: Crumb holds the bakery bag up to the lens, takes the bite and says "Okay. This croissant is ridiculous." in the base clip's voice.

What to check before you keep it: the character matches the sheet from every angle the clip turns through, the hands or stubby arms hold the prop without melting into it, and the mouth roughly tracks the line. Reject and rerun the ones that drift; a new seed is cheaper than a fix in the edit.

Limits that bite

  • Seedance 2.0 takes up to 9 reference images and 3 reference videos per task. Seedance 2.5 takes up to 30 images and 10 videos.
  • Reference videos run 2 to 15 seconds on 2.0, MP4 or MOV, 200 MB or less. Images up to 30 MB, 300 to 6,000 px a side.
  • Real human faces are refused as references. A clip Seedance made on your own account in the last 30 days, untouched, is the exception.
  • The output URL lives for 24 hours. Copy the video to your own storage the moment the task succeeds.
  • Turning Seedance 2.x on in BytePlus ModelArk takes $30 of credits or a resource pack. Individual accounts run 3 tasks at once.

What one variant costs

StepToolCost
Character designChatGPT, one messageIncluded in ChatGPT
Reference sheetChatGPT, one follow-upIncluded in ChatGPT
8-second base clip, 720p, 9:16Seedance 2.0 at $7/M tokens$1.21
8-second character swap, 720pSeedance 2.0 with video input at $4.3/M tokens$1.49

Step 5: cut the ad

The character carries the first two seconds. The product sits inside the bit, and the offer lands in the last two.

  • The character on screen in the first two seconds, not saved for the end card.
  • One bit per ad. Crumb is tired. Gloria judges. Monty poses.
  • The product inside the bit: Crumb is the croissant she is eating.
  • Burned-in captions, 9:16, the offer in the last two seconds.
  • The same reference sheet every week, so week ten looks like week one.
Instagram profile for Jeff D'La Cross, an AI character with a black cross on his head, a pink shirt and a green tie, the same look in every post
Jeff D'La Cross. Five posts, one look: the cross, the pink shirt, the green tie.

Director by Sprites · private beta

Keep the pipeline full. Every Monday.

Director is a full creative team for your Meta ads. Every Monday you get finished, on-brand video ads, reviewed by a human. You pick the winners. Sprites ships the campaigns.

  • Strategy, hooks, scripts, shooting and editing, end to end
  • New concepts before the current winner fades
  • No prompting, no endless revisions

AI mascot: questions

What is an AI mascot?

An AI mascot is a brand character generated with AI and reused across every ad, like a Duolingo owl you can make in an afternoon. It works because it is the same character every time, so people start to recognise it.

How do I make a consistent AI character?

Design the character once in ChatGPT, then ask for a reference sheet with a front, three-quarter and full-body view on one plain background. Give that same sheet to your video model as the reference on every job.

Can ChatGPT make a character reference sheet?

Yes. Generate the character, then in the same chat ask it to turn the character into a reference sheet with three views on one background, keeping every detail identical. The sheet prompt on this page is the one that made all three sheets shown.

How do I use Seedance for an AI character video?

Send the reference sheet as a reference_image and a short clip as a reference_video to the Seedance 2.0 task endpoint, with a prompt that says which person to replace with which character. Poll the task until it succeeds and download the video within 24 hours.

Why does Seedance reject my UGC video?

Seedance 2.0 refuses reference images and videos that contain real human faces. Generate the base clip in Seedance on your own account first, then use that untouched clip as the reference video within 30 days.

How much does an AI character ad cost to make?

The character and its sheet cost one ChatGPT conversation. On BytePlus list prices an 8-second 720p base clip is about $1.21 and the character swap about $1.49, so under $3 of video per variant before editing.

Want a weekly pipeline of these finished?

Director delivers finished, human-reviewed video ads every Monday. You pick the winners. Sprites ships the campaigns.