---
title: "YouTube to reel: plan it step by step, on your licence"
method: POST
path: "/v1/studio/youtube-reel"
tags: ["Edit"]
---

# YouTube to reel: plan it step by step, on your licence

`POST /v1/studio/youtube-reel`

## Request

- Base URL: `https://apihub.co.il`
- URL: `https://apihub.co.il/v1/studio/youtube-reel`
- Auth: HTTP bearer

Turns a YouTube video into a vertical reel, one step at a time — call it again with each step's result. It looks at your licence first: with a declared licence (your own channel, a video YouTube marks Creative Commons, or written permission) the file is taken (POST /v1/youtube/videos/{id}/file records your declaration with it — open to every account, closed for one that took files it had no rights to) and the reel is cut from its best seconds — the video's own striking shots laid over its speech as cut-aways (`inserts`), captions, a hook, the CC BY credit line on screen, 9:16. With your own footage too: your commentary with the video's shots inserted on your words. Without a licence the file is never taken: a commentary reel on your own recording (it writes you the script when you have none) with CC0 stock clips and short quotes of the video on your words. Each answer carries the stage, the licence verdict, the next call with a ready body — Gemini watching the link (POST /v1/ai/text, nothing downloaded), the file, the transcripts, the stock search — and at the end ONE body for POST /v1/studio/edit. Nothing is rendered or charged here; price every next call with its /estimate. Recipe: /skills/full-youtube-reel.md

**Billing:** Read request — the plan is free; every step it names is priced by its own endpoint · **Rate limit:** 60/min

## Headers

- `Idempotency-Key` string
- `X-Tag` string

## Request body

- object
  - `plan` object: The picker's answer: `output.json` of the POST /v1/ai/text call this endpoint gave you
  - `clips` object[]: commentary: the stock clips you found for the plan's `broll` queries
    - `url` string, uri, required: The clip on our storage (POST /v1/stock/save keeps its licence record with the job), or any public clip you may use
    - `broll` integer, required: Which of the plan's `broll` items it is for (its index)
  - `video` object: The video's facts (GET /v1/youtube/videos/{id}). The endpoint looks them up itself when the server can
    - `title` string
    - `channel` string
    - `license` 'youtube' | 'creative-commons'
    - `duration_seconds` number
  - `words` object[]: …or its timed words yourself (ms)
    - `id` string
    - `end` number, required: ms
    - `text` string, required
    - `start` number, required: ms
    - `speaker` string, nullable
  - `credit` string: The credit line shown on screen (CC BY). Default: "<title> · <channel> · CC BY" from the video's facts
  - `licence` 'own' | 'creative-commons' | 'licensed': Your basis for using the video's FILE: own = a channel you control · creative-commons = YouTube marks it Creative Commons (CC BY) and its credit goes on screen · licensed = you hold written permission. Omit when you have none: the recipe makes a commentary reel on your own footage instead and never takes the file
  - `captions` 'classic' | 'hormozi' | 'tiktok' | 'karaoke' | 'one-word' | 'marker' | 'news' | 'neon' | 'quiet' | 'pop' | 'typewriter' | 'bounce' | 'underline' | 'elegant' | 'handwritten' | 'comic' | 'sticker' | 'drama' | 'cinema' | 'shadow' | 'lime' | 'retro' | 'scale' | 'bubble' | 'sport' | 'minimal' | 'slide' | 'volt' | 'neon-glow' | 'marker-tape' | 'keyword-pop' | 'keyword-box' | 'editorial' | 'poster' | 'broadcast' | 'soft' | 'cards' | 'cards-bold' | 'cards-neon' | 'kinetic-pop' | 'fire' | 'gold' | 'glass' | 'vhs' | 'candy' | 'look-clean' | 'look-bold-lime' | 'look-night' | 'look-warm': Caption preset (GET /v1/studio/caption-styles)
  - `cutaways` boolean: licensed: lay the video's own striking shots over its speech (inserts)
  - `file_url` string, uri: licensed: the video's file — `url` of POST /v1/youtube/videos/{id}/file
  - `language` string: The language of the hook, the title and the post text (and of the commentary script)
  - `hook_style` 'box_red' | 'yellow' | 'black' | 'outline' | 'clean' | 'type' | 'punch' | 'glitch' | 'marker' | 'words' | 'box' | 'counter' | 'shake' | 'rise' | 'strike' | 'blur' | 'flash' | 'look-clean' | 'look-bold-lime' | 'look-night' | 'look-warm': Hook preset (GET /v1/studio/hook-styles)
  - `resolution` '720' | '1080'
  - `footage_url` string, uri: Your own recording (a commentary on the video): the reel is built on it, the video's shots (licensed) or stock clips (commentary) inserted on your words
  - `youtube_url` string, required: The YouTube video: a watch / shorts / youtu.be link (or its 11-character id)
  - `footage_words` object[]: …or the footage's timed words yourself (ms)
    - `id` string
    - `end` number, required: ms
    - `text` string, required
    - `start` number, required: ms
    - `speaker` string, nullable
  - `transcript_id` string: licensed, no footage: the transcript of the file (POST /v1/speech/transcripts on file_url)
  - `target_seconds` number: How long the reel should be (±25 %)
  - `footage_transcript_id` string: The transcript of the footage (POST /v1/speech/transcripts on footage_url)

## Response `200`

Completed

- object
  - `id` string: Execution id — stable across internal retries; use it with GET /v1/executions/{id}
  - `status` 'pending' | 'processing' | 'completed' | 'partial' | 'failed' | 'cancelled' | 'timeout'
  - `operation` string
  - `tag` string, nullable: Your X-Tag, if sent
  - `created_at` string, date-time
  - `completed_at` string, date-time, nullable
  - `output` object: Operation result (see each operation). While a Studio render is processing: `stage` (queued · transcribing · downloading · preparing · cleaning_voice · mixing_audio · rendering · finishing), `phase` (the engine's: download · prepare · voice · audio · encode · qa · upload, or null), `progress` (a percent, 0–100) and `progress_fraction` (0–1), `eta_seconds` (seconds left, never below 0) and `estimate_seconds`
  - `error` string, nullable
  - `usage` object
    - `credits_charged` number, nullable
    - `credits_reserved` number
    - `estimated_credits` number
    - `cost_source` 'provider_reported' | 'calculated' | 'estimated' | 'null', nullable
    - `provider_usage` object, nullable: Normalised consumption, e.g. { VIDEO_SECOND: 22.4 }
  - `balance` object
    - `available` number
    - `reserved` number

## Other responses

- `400`: Invalid input
- `402`: Insufficient credits / project budget
- `404`: Resource not found (or not yours)
- `429`: Rate limited
- `503`: Service temporarily paused

---

[API](https://skmtc.dev/apihub/apis/apihub-one-api-for-chat-image-video-ai.md) · [All operations](https://skmtc.dev/apihub/apis/apihub-one-api-for-chat-image-video-ai/llms.txt) · [OpenAPI document](https://skmtc.dev/apihub/apis/apihub-one-api-for-chat-image-video-ai/revisions/a8caa42835ce?raw)
