PORTAL / LIBRARY / motion-ad-generator

[ CREATIVE ]

/motion-ad-generator

Generates a fully finished, export-ready branded video ad using Creatomate — no CapCut step, no manual editing.

Download the skill file (.md)

Placeholders like ACME Agency, <id> and you@example.com mark values that are per-agency — your install fills them with YOUR clients and accounts. If a section references a helper script you don't have yet, it ships with that workflow's install.

Skill: /motion-ad-generator

Overview

Generates a fully finished, export-ready branded video ad using Creatomate — no CapCut step, no manual editing. Canva-style: animated text, brand images (Krea Nano Banana), ElevenLabs voiceover, background music, brand colors.

What this skill produces:

What this skill does NOT do:

When to use:

Trigger:


Critical Files


Script Format

Write this to ACME Agency/clients/<ClientName>/motion-ads/<campaign-slug>/script.json before running the pipeline:

{
  "client": "ClientName",
  "campaign": "<id>",
  "adType": "motion-graphics",
  "targetDuration": 20,
  "voScript": "Pune 48 riječi za 20 sekundi. Kalibriraj prema formuli: targetDuration × 2.4 = broj riječi.",
  "headline": "Kratki, udarni naslov — max 6 riječi",
  "subheadline": "Benefit ili specifikacija (opcionalno)",
  "cta": "Zatraži besplatnu konzultaciju",
  "brandColors": {
    "primary": "#1A4F8A",
    "accent": "#D59C44",
    "text": "#FFFFFF"
  },
  "musicMood": "professional",
  "imagePrompts": [
    "Modern dental clinic interior, Croatia, bright professional photography, no people, wide shot, 9:16 vertical",
    "Close-up of healthy white teeth and warm smile, soft studio light, authentic Croatian aesthetic",
    "Titanium mini implant screws macro photography, gold accent lighting, clean white background"
  ]
}

Campaign slug: <keyword>-<offer/audience>-<YYYY-MM> e.g. <id>


VO Calibration — CRITICAL

Same rule as cinematic pipeline:

ElevenLabs Croatian ≈ 2.3–2.5 words/second
Formula: targetDuration × 2.4 = target word count
Example: 20s = 48 words | 25s = 60 words | 30s = 72 words
Count words BEFORE saving script.json. Mismatch = VO ends before video.

Music Moods

MoodUse when
professionalClinics, B2B, services, authority brands
energeticFitness, youth audience, product reveals
warmLifestyle, family, wellness, emotional appeal
emotionalTestimonials, transformation stories
neutralLuxury, real estate, minimalist brands

Image Prompts

Write 2–3 prompts. Each image fills the upper ~55% of the 9:16 frame for one phase of the video (hook → benefit → CTA). No text needed in images (text is added by Creatomate). Tips:


Preflight (run BEFORE any Krea/ElevenLabs/Creatomate call)

Motion ads compose multiple paid services (Krea images + ElevenLabs VO + Creatomate render). One missing piece = whole pipeline wasted. Validate all of them upfront.

  1. Client exists in clients.json. Resolve canonical key.
  2. Required env vars: KREA_API_KEY, ELEVENLABS_API_KEY, CREATOMATE_API_KEY. If any missing → abort, name them.
  3. Script JSON has all required fields: campaign, headline, cta, voScript, imagePrompts[], brandColors. Missing any → abort.
  4. imagePrompts[] length is 1-6 (rendering more is wasted; rendering 0 = no visuals).
  5. voScript word count matches targetDuration per the calibration table in this SKILL.md (## VO Calibration). If mismatch → abort with the expected range.
  6. musicMood is one of: professional, energetic, warm, emotional, neutral. Reject anything else.
  7. brandColors.primary and brandColors.accent are valid hex (#your-channel). Required by Creatomate templates.
  8. Croatian/German diacritics check in voScript — warn if you see s/z/c/d where š/ž/č/ć/đ should be (ElevenLabs needs correct chars).
  9. drive_folder_id reachable if --drive enabled.
  10. Slack channel resolves if reporting enabled.
  11. Creatomate image transport: images are inlined as data:image/jpeg;base64,... URIs via toDataUri() (from lib/creatomate.mjs). No external host required. catbox.moe was the prior dependency — it's now HTTP 412 banned (2026-05-26) and 0x0.st is 503 indefinitely. See <id>.md.

If all checks pass, log "preflight: OK (n images, voscript=Xs, music=mood, est cost=...)" and proceed.


Workflow

Step 0 — Client lookup

Read ACME Agency/clients/clients.json. Extract:


Step 1 — Brand research

Check for ACME Agency/clients/<ClientName>/brand-dna.md. Need at minimum:

If brand-dna.md doesn't exist: scrape website via Firecrawl, extract colors and tone, write brand-dna.md.


Step 2 — Brief + script.json

If --brief was provided: use it directly.

If not, ask 4 questions:

  1. What's this campaign about? (offer, product, key message)
  2. Target audience?
  3. Duration? (15s / 20s / 30s) — default: 20s
  4. Music mood? (show the mood table) — default: professional

Write script.json to motion-ads/<campaign>/script.json.

Show user a summary before running:

Campaign:  <id> | Duration: 20s | Music: professional
Headline:  "Bezbolni mini implantati — za samo 2 sata"
Subheadline: "Bez rezanja. Bez opće anestezije."
CTA:       "Zatraži besplatnu konzultaciju"
VO:        48 words ✓ (20s × 2.4)
Images:    3 prompts
Proceed?

Step 3 — Run the pipeline

node ACME Agency/scripts/motion_ads_generate.mjs "ClientName" \
  --script "ACME Agency/clients/ClientName/motion-ads/<campaign>/script.json" \
  [--voice <voice_id_or_name>] \
  [--no-slack] [--no-drive]

Pipeline phases:


Output

ACME Agency/clients/<ClientName>/motion-ads/<campaign>/
├── script.json
├── voiceover.mp3
├── image-01.jpg
├── image-02.jpg
├── image-03.jpg
├── final-ad.mp4        ← finished, upload-ready
└── manifest.json

Drive: <ClientFolder>/Motion Ads/<Year>/<Month>/<campaign>/

Verification (run AFTER pipeline completes — confirm the MP4 actually shipped)

Check ALL of these before declaring done:

If any check fails, name the gap explicitly. Most common Creatomate failure mode is silent black screen — check video file size as the canary.


Tips