# Skill: full/youtube-reel — "מיוטיוב לריל" (Complete video)

A YouTube video becomes a vertical reel, on your rights: search YouTube (Creative Commons only, when the video is not yours) or bring a link, and Gemini watches it where it is and plans the reel — its strongest seconds, a hook, a title and a post. With a licence (your own channel, a Creative Commons video, or written permission) the file is taken and the licence kept with the job; the reel is cut on sentence boundaries, the video's own striking shots are inserted over the speech as cut-aways, captions and the hook are burned in and a CC BY credit stays on screen — one render, 9:16. Without a licence the video's file is never used: it becomes a commentary on your own recording (the script is written for you), with CC0 stock clips and short quotes of the video on your words.

**Includes:** a YouTube search or a link — your licence decides the path · Gemini watches the video and picks the reel · its strongest seconds, never cut mid-word · the video's own shots inserted as cut-aways · captions and a hook · the CC BY credit line on screen · no licence: a commentary on your own footage, with stock clips and quotes · optional: dubbed
**Built on:** `POST /v1/studio/youtube-reel` (the stages, the licence verdict, the one render body): `keep` on sentence boundaries, the video's own shots as `inserts` (cut-aways), hook `punch` + captions `classic` ("קלאסי"), the CC BY credit as a `texts` line
**Price:** 115–195 credits per finished minute · 30 s ≈ 80–155 credits
**Uses:** `/v1/youtube/search` · `/v1/studio/youtube-reel` · `/v1/ai/text` · `/v1/youtube/videos/{id}/file` · `/v1/speech/transcripts` · `/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.** Gemini 3.5 Flash (`quality: "balanced"`) watches the YouTube link once, where it is, and writes the plan; AssemblyAI
transcribes the file (or the customer's footage); the rest is ours — the planner, the file transfer, one render. Gemini and the
transcript are priced by the source's length, the render by the reel's.

---

## 1. Find the video (or take the link)

```jsonc
GET /v1/youtube/search?q=<what the customer wants>&license=creative-commons&duration=medium   // CC BY videos only — when the customer has no rights of their own
GET /v1/youtube/videos/{id or link}                                                          // title, channel, length, license: "youtube" | "creative-commons"
```

A search costs 100 of the server's 10,000 daily YouTube units (about 100 searches a day for everyone) — search once,
narrowly, and reuse the results. A link the customer sends needs no search.

**Rights first — ask, never assume.** Which is it: `own` (a channel the customer controls), `creative-commons` (YouTube marks
the video Creative Commons — its credit line goes on screen), `licensed` (written permission from the owner), or none?
Only a declared licence AND the account's YouTube switch (`youtube_files_not_enabled` until we turn it on — the customer
asks through the feedback button and names the channel) take the video's file. Without them the reel is a **commentary**:
the customer's own recording about the video, with stock clips and short quotes of it — the YouTube file is never used.
A `creative-commons` declaration for a video YouTube lists under its standard licence is refused (`license_mismatch`).

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

## 2. The plan — call the planner, then do what it says (it answers at once, 1 credit a call)

```jsonc
POST /v1/studio/youtube-reel
{ "youtube_url": "<link>", "licence": "creative-commons", "credit": "<the credit line>", "target_seconds": 40, "language": "he" }
// → stage "watch", path "licensed" | "commentary", licence { declared, files_allowed, file, reason }, video { title, channel… },
//   next: [ { "method": "POST", "path": "/v1/ai/text", "body": { "media": [ { "url": "<link>", "type": "video", "fps": 1 } ], … } } ]
```

Every answer names the **stage**, the **path** and the **next call with a ready body**. Make that call, then call the planner
again with the same fields plus what the call gave you. Send each next body to `<path>/estimate` first when the customer
wants the price before it runs.

| stage | you send back | what it means |
|---|---|---|
| `watch` | `plan` = the `/v1/ai/text` call's `output.json` | Gemini watched the link where it is (nothing downloaded) and wrote the reel |
| `take_file` | `file_url` = the file call's `output.url` | licensed: `POST /v1/youtube/videos/{id}/file` with the declaration — the licence is recorded with the file (`output.source`) |
| `transcribe` | `transcript_id` (the file) or `footage_transcript_id` (the footage) | the words everything is anchored to, and the captions |
| `find_clips` | `clips: [{ "broll": <index>, "url": "<POST /v1/stock/save url>" }]` | commentary: a CC0 stock clip for each b-roll query (an empty list = quotes only) |
| `record` | `footage_url` + `footage_transcript_id` | commentary without footage: the plan's `script` for the customer to record (vertical) |
| `render` | — | `edit`: the one `POST /v1/studio/edit` body |

## 3. What the render is

**Licensed, no footage** — the reel is cut from the video itself:

```jsonc
POST /v1/studio/edit               // x-wait-ms: 110000
{
  "video_url": "<file url>",
  "keep": [ { "start": 224.62, "end": 257 } ],                 // the plan's spans, moved off the words they would cut
  "words": [ { "id": "w0153", "text": "Nothing", "start": 224742, "end": 225052 }, … ],   // the file's words: nothing is transcribed again
  "captions": { "style": "classic" },
  "hook": { "text": "תזכיר לה מה היא *אהבה*", "duration": 3, "style": "punch" },
  "inserts": [ { "id": "cutaway1", "url": "<file url>", "from": 31, "at": { "word": "w0169", "edge": "start" }, "duration": 3,
                 "mode": "cut", "audio": "mute", "fit": "blur", "transition": { "type": "crossfade", "ms": 160 } } ],
  "texts": [ { "id": "credit", "text": "Tears of Steel · Blender Foundation · mango.blender.org · CC BY 3.0", "start": 0, "duration": 32.38, "preset": "small", … } ],
  "audio": { "normalize": true },
  "output": { "aspect_ratio": "9:16", "resolution": "1080", "fit": "blur", "quality": "high" }
}
```

- **Cut-aways are `inserts`**: another moment of the same file (`from`, its in-point) laid over the speech while the dialogue
  goes on (`audio: "mute"`), anchored to the word it lands on — the render puts it on that word's frame through the cuts
  and reports it in `elements` (kind `insert`).
- A wide film keeps its whole frame over a blurred copy (`fit: "blur"`); a vertical video fills the frame (`crop`).
- **CC BY: the credit line stays on screen** the whole reel (the `credit` text, small, at the top) — and goes into the post text.

**Licensed, with the customer's footage** — their commentary with the video's shots inserted on their words:
`inserts` `during` their words, `mode: "cut"`, `audio: "duck"` (the shot's sound 14 dB under their voice), `fit: "blur"`.

**Commentary (no licence)** — the customer's footage, pauses cut, captions, the hook, the stock clips `during` their words
(`mode: "cut"`, silent) and the video's quotes on white cards naming the channel (`texts`, preset `pill`). No YouTube file.

## 4. Optional: dub it

The reel's cut, in another language: `/skills/full-dub-video.md` from its step 2, on the render's `url` (a voice of the new
language fitted to the speaker's phrases; captions of the dub). The licence of the source still holds.

## What the example cost

The example on /skills (30.9.2026): "Tears of Steel" (12 minutes, CC BY) → a 32.4-second reel:
the planner 4 (4 calls) · Gemini watching the film 45 · the file 10 · the transcript 17 · the render 42 —
**118 credits**. Gemini and the transcript are priced by the SOURCE's length (a 5-minute video ≈ 26 for both,
a 20-minute one ≈ 100), the render by the reel's (≈ 1.3 credits a second at 1080p) — quote the customer the sum of the
estimates, then the real bill from `GET /v1/usage?tag=<job>`, which also lists the job's `sources` (the file and the
licence it was taken under).

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.
