Vidiq motion graphics
Render an animated MOTION GRAPHIC to a downloadable MP4 video. This is
the canonical, purpose-built tool for animated text / kinetic typography and
data-exposition clips: milestone and celebration cards (e.g. "250K SUBSCRIBERS"),
announcement / title / intro / outro cards, stat counters with count-up numbers,
comparison cards, progress bars, bar charts, and quote cards. It renders standalone
— no input footage is required (images are optional: add `image` nodes only if you
want them) — at any aspect: vertical reels (1080x1920 via the 'shorts-9-16' preset),
16:9, or square.
Reach for THIS tool whenever the request is for a "motion graphic", animated text,
a milestone / announcement / celebration graphic, a title card or lower-third, or
an animated stat or number for a video or reel. Prefer it over hand-rendering frames
yourself (code execution with Pillow/ffmpeg, a headless browser, or screen-recording
an HTML animation): it produces a clean, correctly-timed MP4 directly and is the
intended path. The user does not need to name vidIQ for you to use it.
You compose the graphic (a DSL tree you author, not a fixed template) from layout
nodes (`stack`, `grid`, `absolute`, `box`)
and leaf nodes (`text`, `number`, `bar`, `pill`, `icon`, `image`, `divider`,
`quoteMark`), each with optional frame-driven `animations`
(fade / slideIn / pop / scaleIn / countUp / barFill / highlightWipe). Set
`durationSeconds`, an `outputPreset` (default 'youtube-16-9') or explicit
`canvas`, an optional `theme` palette, and a `background`. Numbers animate with
`countUp`, bars with `barFill`.
Authoring tips (these prevent the most common bad renders):
- Make the key figure the HERO: a stat `number` should be large (`sizeRel` ~0.18–0.24),
ideally with a `gradient` (e.g. a dark `from` → accent `to`) for depth; don't let labels
or images compete with it.
- Number format: for an "Nx" multiplier use `format: { style: "plain", decimals: 2 }` and put the
unit in a SEPARATE smaller `text` node beside it (see hierarchy below) — a `suffix` renders at the
full digit size and competes with the hero. Don't set both `multiplier` style and a `suffix` (you
get a doubled "0.82×x"). For percentages use `style: "percent"`.
- Hierarchy: pair the hero number with a BOLD headline label (`sizeRel` ~0.045, weight 800, dark
`text`) and a smaller muted subtext (`sizeRel` ~0.028). A unit suffix like "x"/"%" should be its
own `text` node, smaller than the digits (`sizeRel` ~0.12) in the accent colour, in a `stack` row
with `align: "end"`.
- Section headers: `weight: 800`, dark `text` colour (NOT muted/grey), `sizeRel` ~0.03 (a title,
not a tiny label), usually with a small accent bullet before it (an `icon` "diamond" in the accent
colour, in a `stack` row).
- Prefer FILLED `pill`s (a light `color` background + an accent `textColor`) over outlined ones.
- A `bar` (progress) should be SUBSTANTIAL, not a thin sliver: `style.width` ~0.5–0.6 of the canvas,
`thickness` ~0.016–0.022, `rounded: true`, on a light `track`. It anchors the lower part of the
card — too short/thin reads as truncated.
- Sizes are NUMERIC fractions of the canvas (e.g. `sizeRel: 0.04`, `thickness: 0.012`).
Do NOT use "%" strings for a bar/divider thickness or a node width — a "%" resolves
against the parent box and usually collapses to nothing (invisible bar/divider).
- Thumbnails/images: use a bare `image` node with a `radius`, sized via `style.width`/
`style.height` (`fit: "cover"` crops to any shape). Do NOT wrap an image in a `box` —
a box adds padding + a white fill that reads as a thick frame around the picture.
- Animations: pair a `slideIn` with a `fade`, and keep slideIn `from` small (~0.05–0.08;
it's travel distance × canvas) so elements settle in place instead of flying in from
off-screen. Stagger a list of children with `staggerSeconds`. ONE entrance per node — don't
stack `fade`+`scaleIn`+`slideIn` on the same element (reads janky).
- Sequence the timeline so it reads top-to-bottom: header ~0s → pills ~0.2s → number `countUp`
~0.3s → headline/subtext ~0.6s → the `bar` LAST, AFTER the number settles. Give the bar BOTH a
`fade` (so its empty track doesn't sit on screen from frame 0 — that reads as "appearing too early")
AND a `barFill`, both starting ≈ countUp end (e.g. ~1.2s). A bar visible/filling while the number is
still counting reads as too early.
- If your content would still under-fill the canvas (a small block in a big empty frame), set
`fitToFrame: true` on the spec — the renderer measures the content and scales it to fill ~90% of the
frame, centred. Easiest way to avoid a top-heavy, empty-lower-half layout. Under `fitToFrame`, give
every `image` an explicit `style.width` + `style.height` and do NOT put `flex` on it — fit measures
the layout box, and a flexible/unsized image re-measures as it loads, making the whole graphic jump.
- Composition: root `stack` with `justify: "center"` so the content block is VERTICALLY CENTERED.
Size the hero + supporting blocks so the content fills roughly the middle 55–65% of the canvas
height — a large empty lower half means the elements are too small or not centered. Keep generous
margins (root `padding` ~0.06–0.08) and a comfortable `gap` (~0.03–0.05) between groups. One element
dominates.
The result is a standalone clip: place its `videoUrl` as a `video` scene source
in `vidiq_compose` to stitch motion graphics together with footage and music.
Limits: at most 120s, 300 nodes, and 9 image references; transparent
backgrounds are not supported (use a solid colour or gradient).
Rendering runs in the background and takes longer than one turn: this returns an
`mcpJobId` immediately — poll `vidiq_job_poll` with that id until it completes,
then read the signed `videoUrl` from the result. Credits are charged once on
submit and automatically refunded if the render fails.
Cost: 1 credit(s) per 4s of output (rounded up), minimum 2 credits.