# Skill: full/review — "סקירת מוצר" (Complete video)

The Hebrew product-review Reel, measured frame by frame on a creator's chair review: the price counts up in huge green italic with the hook line typed in under it, a whip into the twist in red ("מוגזם?"), tall condensed white subtitles mid-frame, a grey product card with the photo and the qualities ticked one by one as they are said, the product popping in a frame over the blurred speaker, your own clips of the product as cut-aways, and a dark coupon card with the code in green. Jump cuts, wide / medium / close framing, whooshes, ticks and a lo-fi bed 16 dB under the voice. Gemini 3.5 Flash picks the moments; one 720p render.

**Includes:** a price hook: the number counts up in green, the line typed in, a whip into a red twist · tall condensed white subtitles mid-frame · a product card: the photo and its qualities ticked as they are said · the product in a frame over the blurred speaker · your own product clips as b-roll · a coupon card with the code in green · wide / medium / close framing, whooshes and ticks · lo-fi music under the voice · pauses cut
**Built on:** caption cards (`mode: "cards"`), kinetic `texts[]`, `panels`, `inserts` / `overlays`, `looks` and the effects `image-card`, `icon-fly-in` and `circle-highlight`, laid out by `POST /v1/studio/reel-style` (`"style": "review"`); the nearest single looks are hook `counter` and captions `pop`
**Price:** 135–155 credits per finished minute · 30 s ≈ 72–84 credits
**Uses:** `/v1/speech/transcripts` · `/v1/studio/convert` · `/v1/studio/reel-style` · `/v1/ai/text` · `/v1/stock/icon` · `/v1/ai/music` · `/v1/studio/edit`

Base URL: `https://apihub.co.il` · Auth: `Authorization: Bearer <API key>` · Docs: `/docs`
Send the same `X-Tag: <job name>` header on every call of one video; `GET /v1/usage?tag=<job name>` then
returns exactly what it cost. Times in request bodies are **seconds on the edited (output) timeline**.
Unknown fields are rejected with the name of the right field — read the error instead of guessing.
**Files are kept 24 hours** (renders, uploads, generated clips/images/music) — download the finished video.

**Models — the cheapest that do the job.** AssemblyAI Universal-2 transcribes once, Gemini 3.5
Flash (`quality: "balanced"`) watches the video once and picks the moments, ElevenLabs makes a music bed exactly as long as the
video; the sounds are the free CC0 kit, the tick is a free emoji, the photos and clips are yours; no AI video or images.
Everything is priced by the video's length.

---

## 1. Transcribe the video (once)

```jsonc
POST /v1/studio/uploads { "filename": "clip.mp4", "content_type": "video/mp4", "size_bytes": <bytes> }   // a local file → output.url (skip for a public link) · the original file, never a resized copy
POST /v1/speech/transcripts { "audio_url": "<video url>", "language_code": "he", "speech_models": ["universal-2"] }
// → T0, the video's words · Universal-2 · 64 s ≈ 1 credit
// optional — the music level: a WAV of the voice for the planner to measure (`cut_audio_url`); without it the bed sits at 0.25 (0.2 in the review)
POST /v1/studio/convert { "video_url": "<video url>", "output": { "format": "wav" } }                      // x-wait-ms: 90000 · ≈ 0.15 credits a second
```

**One transcript, on the video's own clock.** Every element the planner writes — the title, each subtitle, beat, pill,
chapter card, sticker, zoom and sound — is anchored to a word (`at` a word's id, or `during` a stretch of them).
The render finds the pauses in the sound itself (`remove_silence`, the same numbers every time), cuts them, and puts
each element on the exact output frame its word lands on; its answer reports where every one landed (`elements`:
exact / moved / lost). No second transcription of the cut audio, no reference transcript to put words back from. The
WAV is only where the planner measures the voice, to put the music ≈ 13 dB under it (16 dB in the review).

**Everything below is timed on the cut video's clock.**

A Hebrew product-review Reel, measured frame by frame (a creator reviewing an office chair on Facebook, 69 s, 1080×1920,
24 shots, 8.10.2026): the price counts up in huge green italic with the hook line typed in under it, a whip into the twist
in red, tall condensed white subtitles mid-frame, a grey product card with the qualities ticked as he says them, the product
in a frame over the blurred speaker, b-roll of the product, and a coupon card at the end.

## 2. The first plan — the numbered words and the picker call

```jsonc
POST /v1/studio/reel-style
{ "style": "review", "video_url": "<video url>", "transcript_id": "<T0>", "cut": { "from": "audio", "min_pause_ms": 200, "padding_ms": 70 },
  "cut_audio_url": "<the wav's url>",                                            // optional (the music level)
  "product": { "image_url": "<a photo of the product>", "aspect": "16:9" },      // optional: the card's photo and the spotlight
  "clips": [ { "url": "<your clip or photo of the product>", "about": "what it shows" } ] }   // optional, up to 8
// → output.words    [ { "i": 0, "text": "חמש", "start": 0.12, "end": 0.41 }, … ]   the numbered words
//   output.picker   { "system": "<the review brief>", "prompt": "… A product photo is given: yes. The customer's clips: 0: … Numbered words: …" }
```

It answers at once and costs a read request (1 credit). Upload your photo and clips first (`POST /v1/studio/uploads`).

## 3. Gemini watches the video and picks the moments

```jsonc
POST /v1/ai/text                           // Gemini 3.5 Flash ≈ 8–15 credits, ~40 s
{ "quality": "balanced", "json": true, "max_tokens": 8000, "temperature": 0.4,
  "system": "<output.picker.system>", "prompt": "<output.picker.prompt>",
  "media": [ { "url": "<video url>", "type": "video", "fps": 0.5 } ] }
```

It returns word numbers and short texts only: `corrections`, `face`, `hook` { number, line, punch }, `card` { items },
`spotlight`, `broll` (a clip index and a span of words each), `coupon` { word, label, code } and `music_brief`.

**Your pass before using it** (on the example both were needed): the hook line must be the words he OPENS with (the model once
picked a line at 5.8 s and left the opening bare); the `face` box must hold the face — top of the head and the chin in % of
the 9:16 frame (it once said 10–65 % for a chin at 57 %; a thumbnail, `POST /v1/studio/thumbnail`, settles it); every text
on screen must be his own words; a `number.text` keeps his digits.

## 4. The assets — in parallel

```jsonc
POST /v1/stock/icon { "icon": "fluent-emoji-flat:check-mark-button", "size": 512, "padding": 2 }   // the green tick on the card · free
POST /v1/ai/music { "prompt": "<picks.music_brief>", "duration": <ceil(summary.output_seconds + 1)>, "instrumental": true }   // ≈ 0.95 credits a second
```

The sounds come from the free CC0 kit (a whoosh, a pop, a bell for the ticks, a glitch for the card, a hit for the price and
the code), each at its measured level; send `sounds` { whoosh, pop, ding, glitch, cash } to use your own.

## 5. The final plan and ONE render

```jsonc
POST /v1/studio/reel-style
{ …the body of step 2…,
  …the picks after your pass (without "music_brief")…,
  "icons": { "check": "<the tick png>" },
  "music": { "url": "<music mp3>" } }                  // the volume comes from the measured voice
// → output.edit — the complete body of the render · output.timeline — what happens when (check it) · output.warnings
POST /v1/studio/edit <output.edit>          // x-wait-ms: 90000, then poll GET /v1/executions/{id} · 720p ≈ 0.95 credits a second
```

## What the plan puts in the render

Measured on the reference (1 fps sheets of the whole reel, 6 fps around the hook, the card and the coupon, colours sampled from
the pixels, the caption's x-height measured on full frames; the sound effects and the music listened to by Gemini 3.1 Pro):

| The look (measured) | How the plan does it |
|---|---|
| Hook 0–2.5 s: the price counting up (`₪212 → ₪5,500`) in huge condensed italic green **#48C04C**, the line typed in under it in white, both leaving with a zoom blur | `hook.number` (its `text`, `"₪5,500"`) → `counter` + the line (`typewriter`), Karantina 700 italic (Oswald for Latin) fitted to ≈ 72–84 % of the width, exit `smear`, a slow 1.0→1.07 push, a hit as the count starts |
| A whip into the twist: its 2–3 lead-in words in white, the twist in red **#E8282F** ("ונשמע לכם / מוגזם?") | `hook.punch` → the ≤ 3 words said right before it in white over the twist in red (`pop`), a 0.06 s white flash, a 1.16× punch, a whoosh; no subtitles under the hook |
| Subtitles: 1–3 words, tall condensed heavy white with a soft shadow, x-height 3.4 % of the height, mid-frame (y ≈ 50 %), cut in with a small pop, no highlight | caption cards (`mode: "cards"`, 3 words, one line) in Karantina at 6.2 % (x-height 3.4 %), centred at the chin + 9 % (50–66 %), `cues` = the plan's phrases, `hide_words` under the hook / card / spotlight / coupon |
| On the product footage the same line sits on a dark rounded chip | `captions.placements` with `chip: #000000A6` over every b-roll |
| A product card (4.5 s): light grey **#DADADC** over the whole frame, the product on a dark rounded card with a red / blue fringe, a glitch in; the qualities typed in one by one with a green tick **#70D078**, a ding each | `card.items` (2–4 spans) → a grey panel, `image-card` (the photo, a red edge and a blue glow), `icon-fly-in` ticks (the ✅ Fluent emoji, or green squares) and dark italic lines (`typewriter`) on each item's word, a flash and a glitch in, a whoosh out |
| A 3D wireframe box round the product cut-out over the blurred speaker, a blue label **#2868D8** over it | `spotlight` → `looks` (blur 18, dim) on the speaker, `image-card` (the photo, a white edge and glow), `circle-highlight` (a white box that draws itself), the label on a blue box |
| Manufacturer footage, close-ups and an unboxing between the talking parts | `clips` + `broll` → `inserts` (clips, muted, cut) and full-frame `overlays` (photos), 1.5–4.2 s each, a whoosh in |
| The coupon: a dark rounded card with the code in green **#88E088**, a cash-register hit | `coupon` → `image-card` of a dark card, the label and the code in condensed italic green (`typewriter`), a hit; when it runs to the end the last frame is held 1.2 s |
| Jump cuts between wide, medium and close shots | `remove_silence` 200/70 and the framing per sentence 1.0 / 1.14 / 1.0 / 1.26 (`punch`), a whoosh on the closest |
| Lo-fi hip hop ≈ 85 BPM, low under the voice; whooshes, pops, dings, a cash hit | `music.volume` = 10^((voice LUFS + 2) / 20) — 16 dB under the measured voice; the free CC0 kit (whoosh, pop, bell, glitch, hit) unless you send `sounds`; `audio.normalize` → −16 LUFS |
| A cool, contrasty grade | `color` contrast 1.07, saturation 0.96, temperature −0.06, vignette 0.12; 9:16, 720×1280 |

## Tune it

`hook` (number · line · punch) · `card` · `spotlight` + `product.image_url` / `aspect` · `clips` + `broll` · `coupon` · `icons.check` · `sounds` · `face` · `resolution: "1080"` · `speed` 1–1.25 · `cut: false` to keep every pause. Every field of the returned `edit` can still be
changed before the render.

## What the engine cannot do yet (so the plan does not try)

A 3D wireframe box (a white frame that draws itself instead); gradient text (the coupon's code is solid green); a blur only
behind the coupon card (the card is an opaque dark card); an RGB split on the card (a red edge and a blue glow instead); a
motion-blur whip at a chosen cut (a white flash, a zoom punch and a whoosh instead); his extra price numbers popping round the
speaker (only the hook's own number); the unboxing time-lapse itself (send it as a clip).

## What the example cost and how long it took

The example: the owner's two takes about the product he built — the Vidoo app — joined (74.5 s, Hebrew, 1080×1920, −12.2 LUFS) → 70 s, 720×1280, −16.1 LUFS. The hook "אם בניתם מוצר", then the whip into "לא משתמשים במוצר / זרקו אותו לפח!" in red; the spotlight on "המוצר שאתם רואים פה" (the app's store graphic as the photo); four cut-aways (the app's screens and a crowded CapCut timeline on "בלי להזיז כל פעם את הטיימליין"); a card with two ticked qualities ("לעשות את הכל אוטומטי", "בכמה קליקים"); the coupon card "תכתבו / סוכן" held over the last frame; the bed 16 dB under the voice. The picker put the hook on his opening words by itself and fixed "בהערכת" → "בעריכת"; the pass only fixed the face box (it said 10–65 %, the chin is at 57 %). Made with these steps on the dev server (tag `review-example`, `GET /v1/usage?tag=…`):

| Step | Credits | Time |
|---|---|---|
| Upload the video (170 MB) + the product photo and 5 clips / screens | 7 | ≈ 1 min |
| Transcribe (Universal-2, 75 s) | 2 | ≈ 15 s |
| A WAV of the voice (75 s) | 15 | ≈ 10 s |
| Plan ×2 (POST /v1/studio/reel-style) | 2 | 1–2 s |
| Gemini 3.5 Flash picks | 13 | 43 s |
| The tick icon | 0 | 1 s |
| Music, 72 s | 68 | ≈ 20 s |
| Render (720p, 70 s) | 66 | 51 s |
| **Total** | **173** | **≈ 3.5 min** |

Send `x-wait-ms: 110000` to wait for the render in the same call; if the response is still
`processing`, poll `GET /v1/executions/{id}` until `status` is `completed` and read `output.url`.

## Check the bill

`GET /v1/usage?tag=<job name>` — per call, per operation and the total, in credits. Quote that to the
customer, not the estimate above.

## Rules that keep captions readable on every platform

- **Safe zone.** Keep text inside the middle 80% of the frame: `side_margin` ≥ 6 handles the sides; `margin`
  ≥ 12 keeps the bottom clear of the platform UI (username, buttons, progress bar).
- **A line never leaves the frame** — a line too wide for the side margins is set smaller automatically. Do
  not shrink the size yourself, wrap instead (`max_chars_per_line`).
- **Hebrew has no capitals** — keep `uppercase: false`; it only breaks Latin words mixed into a sentence.
- **Fonts.** `GET /v1/studio/fonts` lists the bundled families and which scripts they draw. A font that
  cannot draw the caption's language is swapped and reported in `warnings`.
- The customer's transcript wins: to fix a word, `GET /v1/speech/transcripts/{id}/captions`, edit the text,
  and send the list back as `captions.captions` — timing is kept when the word count is unchanged.
