A spec AI-UGC ad for a fictional DTC tumbler brand. The creator talks to camera with lip-sync and holds the product throughout. Only the opening changes between versions, so Meta can tell you which hook wins.
Each version is a complete ad. Watch the first three seconds of each one; everything after the cut is identical.
The hook is a separate block, and the body, captions and CTA are shared, so each variant is a clean test of the opening and nothing else.
The whole concept lives in a single brief file. One command turns it into named, ready-to-upload versions, and adding hook number four means adding one line.
$ python3 build/render.py KEEL_C01_H01_v01_916.mp4 14.80 s KEEL_C01_H02_v01_916.mp4 15.06 s KEEL_C01_H03_v01_916.mp4 15.06 s manifest.csv written · qa.json: all checks passed
brief.json
{
"concept": "C01_morning-luxury",
"version": "v01",
"angle": "Want, not need: the small daily luxury of coffee that still tastes and feels right hours later",
"hooks": [
{
"id": "H01",
"type": "talking-head",
"spoken": "Okay, this is the only cup I leave the house with now.",
"overlay": "The only cup I leave the house with",
"source": "main"
},
{
"id": "H02",
"type": "pov-proof",
"spoken": "I made this coffee at seven. Look at it now.",
"overlay": "Made at 7:00. It's 11:40.",
"source": "pov"
},
{
"id": "H03",
"type": "silent-text-asmr",
"spoken": "",
"overlay": "POV: your 11:40 coffee still steams",
"source": "pov_alt"
}
]
}
Angle, script, hooks, overlays and CTA live in a single file. Claude Code writes hook variants from the angle; I pick and tighten them.
The AI creator still and product shots are generated first. The voice is recorded as one take, and the word timestamps from that take drive the captions.
The creator is animated speaking the take, holding the product. Face, mouth and hands are checked frame by frame, and weak takes are redone.
The script renders every hook with the same body, captions and CTA. Names follow brand_concept_hook_version_format, so the results in Ads Manager map straight back to the brief.
Resolution, audio, loudness and length are checked automatically, then frames are checked by eye. The manifest lists every file with its hook and a checksum.
| File | Hook | Type | Length | Checksum |
|---|---|---|---|---|
KEEL_C01_H01_v01_916.mp4 | H01 | talking-head | 14.80 s | 4121dddabc |
KEEL_C01_H02_v01_916.mp4 | H02 | pov-proof | 15.06 s | 47494ae7e0 |
KEEL_C01_H03_v01_916.mp4 | H03 | silent-text-asmr | 15.06 s | 04fd5802cb |
All 3 versions are 1080 × 1920, 30 fps, H.264, 14.9–15.1 s, with no scene breaks inside the talking take.
Every version has a stereo AAC track normalised to -15.0 to -14.8 LUFS (Meta / Reels range), with the music bed kept well under the voice.
Each export is transcribed by machine and compared against the script. The words match, and a repeated phrase in the raw take was cut out before the edit.
Frames checked at full size: five fingers on every visible hand, a stable grip on the product, the same face throughout and no warping around the mouth.
1–2 concepts a day with at least 3 hooks each, revisions within 24 hours. I'm in Thailand (UTC+7), so feedback sent in your afternoon is usually done by your next morning.
Weekly 30-minute session: Monday or Tuesday at 5:30 pm Pacific, which is 8:30 am the next morning for me.