UGC-Style Ads With an AI Presenter Who Holds Your Product
Build AI UGC ads: an invented presenter holding your product, an 8-10 s spoken clip, five 9:16 hook variants, real costs and the AI disclosure rules.
UGC ads look like a normal person filming themselves with a phone: product in hand, a couple of sentences to camera, nothing polished. You can produce that format with AI in three moves. First, a still of an invented presenter holding your product, made in Nano Banana Pro (from $0.07 per image) with real product photos as references. Second, an 8 to 10 second clip where that presenter speaks, using Kling 3.0 for English lines (from $0.0963 per second, sound costs extra) or MiniMax H3 for other languages (from $0.161 per second, sound included). Third, several versions of the opening sentence, with captions added in the editor.
I also cover what five variants cost and the AI disclosure rules you have to follow on Meta, TikTok and under the EU AI Act.
The brief I write for every ad
Before generating, I fill in six lines:
- format: 9:16, since UGC runs on Reels, TikTok and Shorts,
- presenter: a made-up person (age, style, place), never a real person's face without consent,
- product: one to three photos of the actual packaging from different sides,
- script: roughly twenty words, enough for an 8-10 second clip,
- hook: whatever is said in the opening two seconds, written in several versions,
- disclosure: a note that the person and footage are AI-made (rules further down).
Captions, logo and end card come later, in the edit. For an ad without a speaking person (packshot, motion, music), see my AI product ad workflow.
Move 1: the presenter still
My tool for the opening frame is Nano Banana Pro: fourteen reference slots and native 9:16. Packaging photos are attached as references (the Studio field of that name, or image_urls). For a recurring presenter, a previous frame of that person goes in as well. In the text I describe who they are, what their hands do and where they sit, and call the product "the jar from the reference images":
Vertical smartphone selfie photo, 9:16. A woman in her early thirties with shoulder-length
dark hair, natural makeup, oversized beige sweater, sitting on a sofa in a bright living room.
She holds the skincare jar from the reference images at chest height, label facing the camera,
fingers not covering the label. Natural window light, slightly casual framing, looking into
the lens with a friendly half-smile. Keep the product shape, colors and label exactly as in the
reference. No other text, no logos, no watermarks.Things I check before moving on:
- Readable label, no fingers over it. Video models distort hands and lettering most, so both must be right in the still.
- A phone look, not a studio look. A slightly crooked frame and window light feel authentic, which is the whole idea of UGC.
- 2k output. Every later step builds on this picture; it is the wrong place to economize.
- Three or four tries. I keep the one with a legible label and five fingers on each hand.
Keeping one face recognizable over a whole campaign: see consistent characters in AI video.
Move 2: the spoken clip
Now the still is animated, and the prompt carries motion, voice and script. Language decides the model. On 28 September 2026 I gave several models one tricky Polish sentence of twelve words (full write-up):
| Model | Lengths | Misheard words | Audio here |
|---|---|---|---|
| Kling 3.0 | 3-15 s | 10 | paid add-on via generate_audio |
| MiniMax H3 | 4-15 s | 1 / 3 | stereo in every clip |
| Veo 3.1 (Quality) | 8 s only | 0 / 2 | form has no audio control |
| Gemini Omni 1.1 | 4/6/8/10 s | 0 / 0 | no audio listed in the catalog |
Prices: from $0.0963 per second, from $0.161 per second, from $2.53 per video per 8-second clip and from $1.02 per video for a 6-second clip. I counted errors by transcribing each clip with faster-whisper (large-v3, then medium); each model had a single attempt, and the runs went through other API providers. My conclusions for ads:
- English script: Kling 3.0, audio enabled. Kuaishou lists English as supported and it shows. Polish is absent from that list, which matches the ten errors.
- Any other language: MiniMax H3. It slipped only once on a hard sentence, sound costs nothing extra, and an 8-10 second clip fits its limits.
- Veo 3.1 and Gemini Omni 1.1 were the cleanest speakers, yet I ran them elsewhere, and on Kadraris neither form offers an audio control. Render a single test and listen for a voice before you build a campaign on them.
- Gemini Omni 1.1 gets pricier above 6 seconds; check the per-length price in Studio or the cost calculator.
My clip prompt: what happens in the shot, what the voice sounds like, the script in quotation marks with numbers spelled out, and a clear ban on subtitles:
The woman from the first frame looks into the phone camera and talks naturally, slight handheld
movement, she lifts the jar a little when she mentions it. She says clearly in English, warm
friendly female voice, normal pace: "My skin is dry and every cream felt sticky on me.
This one sinks in within a minute." Quiet room ambience, no music, no subtitles,
no on-screen text.Through the API this is one request, with the still in image_url. Kling copies the image's ratio, so a vertical still gives a vertical clip:
curl https://kadraris.com/v1/generate \
-H "Authorization: Bearer $KADRARIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-3.0",
"input": {
"prompt": "The woman from the first frame looks into the phone camera and talks naturally, slight handheld movement. She says clearly in English, warm friendly female voice: \"My skin is dry and every cream felt sticky on me. This one sinks in within a minute.\" Quiet room ambience, no music, no subtitles, no on-screen text.",
"image_url": "https://your-shop.com/ugc/frame-cream.png",
"resolution": "1080p",
"duration": 8,
"generate_audio": true
}
}'The file comes from GET /v1/tasks/{id}. I compare the speech against the script using a transcript (faster-whisper, or CapCut's auto-captions), because a swallowed word ending is easy to miss by ear.
Move 3: five openings for the same ad
The opening sentence does most of the selling in UGC. I keep the still, the product and the rest of the script identical, and change only the first line:
- pain point: "Tight, flaky skin by noon? That was me every winter.",
- question: "Why does every rich cream leave my face shiny?",
- concrete claim: "Two pumps, sixty seconds, and it's gone into the skin.",
- contrast: "Rich enough for dry skin, light enough for makeup.",
- instruction: "Wait, read the label on your moisturizer first."
Each one talks about product properties, not about invented personal experiences; the ethics section explains why. In code, five versions are just a loop:
import os, time, requests
API = "https://kadraris.com/v1"
KEY = os.environ["KADRARIS_API_KEY"]
HEADERS = {"Authorization": f"Bearer {KEY}"}
STILL = "https://your-shop.com/ugc/frame-cream.png"
TAIL = "It sinks in within a minute and does not pill under makeup."
OPENERS = [
"Tight, flaky skin by noon? That was me every winter.",
"Why does every rich cream leave my face shiny?",
"Two pumps, sixty seconds, and it's gone into the skin.",
"Rich enough for dry skin, light enough for makeup.",
"Wait, read the label on your moisturizer first.",
]
def prompt_for(opener):
return (
"The woman from the first frame looks into the phone "
"camera and talks naturally, slight handheld movement. "
"She says clearly in English, warm friendly female "
f'voice: "{opener} {TAIL}" Quiet room ambience, '
"no music, no subtitles, no on-screen text."
)
jobs = []
for opener in OPENERS:
body = {"model": "kling-3.0",
"input": {"prompt": prompt_for(opener),
"image_url": STILL,
"resolution": "1080p", "duration": 9,
"generate_audio": True}}
job = requests.post(f"{API}/generate", headers=HEADERS,
json=body, timeout=30).json()
print(job["id"], job["estimated_cost"])
jobs.append(job)
# wait for every clip and print its link
for job in jobs:
while job["status"] not in ("succeeded", "failed"):
time.sleep(10)
job = requests.get(f"{API}/tasks/{job['id']}",
headers=HEADERS, timeout=30).json()
out = job["output"][0]["url"] if job["output"] else job["error"]
print(job["status"], out)For a non-English script, switch model to minimax-h3, set resolution to 768P and drop generate_audio. Result URLs are temporary, so fetch the files as soon as they are ready. With dozens of variants, a webhook beats a polling loop.
Reusable template
I paste this skeleton into each new project and replace the bracketed parts. Part one is for the still, part two for the clip:
[STILL - image model, references: product photos]
Vertical smartphone selfie photo, 9:16. [AGE AND LOOK], [CLOTHES],
[PLACE: kitchen / car / bathroom / living room]. [Holds / points at] the [PRODUCT]
from the reference images, label facing the camera, fingers not covering the label.
Natural [window / daylight / evening lamp] light, casual framing, looking into the lens.
Keep the product exactly as in the reference. No other text, no logos, no watermarks.
[CLIP - video model, first frame: the still above]
The [person] from the first frame looks into the phone camera and talks naturally,
slight handheld movement, [GESTURE WITH THE PRODUCT]. She/He says clearly in [LANGUAGE],
[VOICE: warm female / low calm male], normal pace: "[HOOK] [PRODUCT FEATURE]."
[AMBIENT SOUND], no music, no subtitles, no on-screen text.Script rules: spell out every number, keep it to about twenty words, and leave out any brand name the voice might mangle; the brand goes on screen as text instead.
Finishing the vertical cut
The vertical format is fixed in move 1, since the still decides the clip's ratio. In the edit I:
- shave half a second off either end when the presenter starts stiffly or cuts off a syllable,
- add captions as an editor layer, never through the prompt (hence
no subtitles), - place captions in the center band, clear of the icons on the right and the description at the bottom,
- put the AI notice and ad disclosure in two places, on screen and in the post text,
- review the file on a phone, muted, since that is how most people scroll.
Budget for five variants
Assumptions: a single presenter still, five openings of 8-9 seconds, each rendered twice. For Veo 3.1 I count whole 8-second clips, its only length.
| Line | Amount | Kling 3.0 + sound | MiniMax H3 768P | Veo 3.1 |
|---|---|---|---|---|
| Presenter still | 4 tries | 4 × from $0.07 per image | 4 × from $0.07 per image | 4 × from $0.07 per image |
| Spoken clips | 90 s (Veo: 10 clips) | 90 × from $0.0963 per second | 90 × from $0.161 per second | 10 × from $2.53 per video |
Editing, captions and the logo cost nothing from your balance. The shortcodes pull live rates from the pricing page. Note that Kling's number is its cheapest tier (720p, silent); the 1080p rate with audio is higher, and you see it in Studio before generating. MiniMax H3 starts at 768P, and Veo 3.1 has one rate for both 720p and 1080p. Anything that ends as failed is free. For Kling with audio, or Gemini Omni at longer lengths, the AI cost calculator gives exact totals. Funds never expire and nothing renews.
Disclosure, fake reviews and the law
To a viewer, a synthetic presenter is indistinguishable from someone filmed on a phone. My own rules are simple. Every such ad carries an AI label. The presenter never claims to be a buyer. And the script never contains an invented testimonial such as "I've used it for a month and I'm hooked", because nobody stands behind those words. The presenter sticks to features anyone can verify. Here is what the regulations and platforms said when I checked on 4 October 2026:
- EU AI Act, Article 50. From 2 August 2026, publishers of deepfakes, that is lifelike pictures, audio or video that a viewer could take for real, have to say the content was made or altered by AI. Penalties can reach EUR 15 million or 3% of worldwide annual turnover. A believable "shopper" speaking to the lens is a likely case, so I label all of them. Read more: Commission fact page on AI transparency, full text of the AI Act.
- Meta. On Facebook and Instagram, ads built or heavily changed with generative tools get an "AI info" marker, and Meta also reads metadata from outside tools. Viewers find it in the "About this ad" menu. Political, election and social issue ads require the advertiser to declare AI use. Read more: Meta help page on AI labels in ads, Meta policy for political and social issue ads.
- TikTok. Ads Manager has a checkbox for AI-generated content during setup. It applies when visuals or audio are entirely synthetic or substantially altered, and after submission you can only remove it by replacing the creative. Spark Ads fall under the Community Guidelines for AI content. Read more: TikTok help on ad disclaimers.
- Testimonials. EU consumer law (the Omnibus Directive) treats fake or commissioned consumer reviews as a prohibited practice. In the United States the FTC rule on reviews bans testimonials from people who do not exist, AI-generated ones included. Read more: Directive 2019/2161, FTC announcement.
None of this is legal advice. Campaigns for clients, and anything in health, finance or supplements, should get a lawyer's review of the script.
Questions
Can the same presenter appear in many ads?
Yes. Save a good still of the presenter and add it as an extra reference image in every new frame, together with the product photos. Keep the description of face, hair and clothing identical in each prompt.
Should the presenter say the brand name?
I avoid it. Video models often mispronounce brand names, and a wrong pronunciation looks careless. Put the brand in a caption or in a separate voice-over during the edit.
How do I check that the speech matches the script?
Run the clip through a transcription tool such as faster-whisper or CapCut's auto-captions and compare the text with your script word by word. Listening alone tends to miss dropped endings.
Is a label needed if I only use the presenter on my own channel?
Yes, in practice. The AI Act disclosure rule covers realistic generated content regardless of who posts it, and TikTok and Meta have their own labeling. I add a note both in the caption and on screen.


























