# Skill: full/human-video — "וידאו טבעי — אתם מדברים למצלמה, בלי שזה נראה AI" (Complete video)

You, talking to the camera — without a camera, and without the look that gives AI videos away. Generated presenters are too even: the same pace, the same tone, both hands moving together, a fixed stare. This recipe is what the owner learned from a real Israeli creator's reel, over three versions of his own video: the start frame is a photo edit of your photo shot like a phone propped on your desk (a little low and tilted, uneven window light, a lived-in room); the script is spoken Hebrew with a few real hesitations; Gemini Omni moves you like a real, slightly restless person — one hand talks, gestures are dropped halfway, the eyes glance away when searching for a word — with one acted moment a line. Every take is watched before it is kept. Your own cloned voice reads correct Hebrew, quick and casual (never Gemini's own voice), HeyGen puts your lips on it, and the lines are joined with jump cuts and a punch-in, captions with key words in lime and a quiet bed. Only your own face and voice, or someone who agreed.

**Includes:** your face from one photo, filmed like a phone propped on your desk — not a studio · a script in spoken Hebrew with a few real hesitations (אממ, a word started again) · Gemini Omni moves you like a real, slightly restless person: one hand talks, gestures dropped halfway, a glance away · one acted moment a line — a real nose scratch, a mock, a look at your own hands · every take watched by Gemini: no letters in the frame, the same face, natural hands · your own cloned voice reading correct Hebrew, quick and casual · your lips on your voice (HeyGen Precision) · jump cuts with a punch-in, captions with key words in lime, a quiet music bed
**Built on:** a photo edit of your photo as the start frame (`POST /v1/ai/image`), Gemini Omni clips from it (`POST /v1/ai/video`, `gemini-omni-1.1-flash`), your cloned voice (`POST /v1/ai/voice`), HeyGen lips (`POST /v1/video/lipsync`), the lines joined with jump cuts (`POST /v1/studio/merge`) and one render for the captions `keyword-pop` from the voice's own words, the punch-ins, a quiet bed and the credit
**Price:** 4000–12500 credits per finished minute · 30 s ≈ 2100–6300 credits
**Uses:** `/v1/studio/uploads` · `/v1/ai/image` · `/v1/ai/text` · `/v1/ai/video` · `/v1/ai/voices/clone` · `/v1/ai/voice` · `/v1/speech/transcripts` · `/v1/studio/convert` · `/v1/video/lipsync` · `/v1/studio/merge` · `/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.** Nano Banana Pro (`quality: "best"`) edits your photo into the start frames; Gemini 3.1 Pro writes the script and
watches every take; Gemini Omni (`gemini-omni-1.1-flash`, 720p) films each line — always 10 seconds a take, most of the price;
your ElevenLabs clone reads it on eleven_v4 with the Hebrew director inside the call; AssemblyAI checks the words and finds
where each take starts talking; HeyGen Precision draws the lips; the cuts and the mix are ours. Priced by the number of lines.

---

## 1. Your face and your voice — yours only

**Only your own face and your own voice** (or someone who gave written permission): the video shows a real person saying
things they never filmed. One sharp photo of you, facing the camera, chest-up, natural light, no sunglasses; your voice
cloned once (`/skills/full-natural-voice.md` step 1, ≈ 282 credits, kept for the account).

```jsonc
POST /v1/studio/uploads { "filename": "me.png", "content_type": "image/png", "size_bytes": <bytes> }   // free → PUT the file to upload_url → url
```

## 2. The start frame — a phone propped on a desk, not a studio

The single biggest step away from "AI": not a clean presenter shot but the frame a real person gets when they film
themselves — the phone a little low and tilted, uneven window light, a lived-in room, a soft front camera. The face stays a
**photo edit of your photo** (a frame drawn "from a reference" drifts to another face).

```jsonc
POST /v1/ai/image { "quality": "best", "aspect_ratio": "9:16", "resolution": "2K", "reference_images": [ "<your photo>" ],
  "prompt": "PHOTO EDIT of the FIRST image (not a new image). Keep the person's head EXACTLY as it is in the photo: the same face, hair, eyes, eyebrows, nose and skin texture, pixel-faithful. Do not redraw, slim, beautify, rotate, sharpen or age the face.\nCHANGE THE CLOTHES AND THE WHOLE SHOT: <clothes, e.g. a plain dark navy t-shirt>, clean but worn the way a real person wears it — natural wrinkles from sitting, the neckline a little uneven.\nIt is a frame from a real, imperfect video they film themselves: the phone is propped on the desk against something, a bit BELOW eye level so it looks slightly up at them, the frame tilted about 2 degrees, the person slightly off-centre, chest-up and close, hands resting loosely on the desk edge at the bottom of the frame. Ordinary mixed light, NOT a studio: daylight from a window blows out a little and lights one side of the face, the other side is in soft shadow, a warm lamp out of frame adds a slight warm spill; a little skin shine. Behind them <their real room, e.g. a lived-in office: a shelf edge, part of the window>: a few ordinary objects, a cable, the back of the chair — nothing staged. Front-camera look of a phone: slightly wide lens, a bit soft, visible noise in the shadows, mild compression, no bokeh, no colour grading, no beautification. NO text, captions or logos anywhere." }        // ≈ 53 credits — make two, keep the one that looks most like you
POST /v1/ai/image { "quality": "best", "aspect_ratio": "9:16", "resolution": "2K", "reference_images": [ "<your photo>", "<the frame you kept>" ],
  "prompt": "PHOTO EDIT of the SECOND image. Keep EVERYTHING exactly the same — the same room, light, camera angle, tilt, framing, background objects, clothes and wrinkles — and keep the face exactly as in the FIRST image (pixel-faithful). Change ONLY the pose: caught mid-sentence, the right hand raised loosely in front of the chest with the fingers bunched together, the other hand still resting on the desk edge, the mouth slightly open as if talking. Hands with natural anatomy, five fingers each." }         // ≈ 53 — the second pose, edited FROM the first so the room never changes
```

The lines alternate between the two frames: every jump cut then lands on a slightly different pose of the same shot, the
way a real creator's cuts look.



## 3. The script — spoken Hebrew, with a few hesitations

```jsonc
POST /v1/ai/text { "quality": "best", "json": true,
  "system": "You write a short talking-to-camera script for an Israeli creator, in natural SPOKEN Israeli Hebrew — the way people really talk, not the way they write. Speaker's gender: <male|female> (use the matching forms).\nRules: 3-6 lines; every line 4-9 seconds when said (8-18 words) and ends on a natural pause; short sentences, a question to the viewer, slang where it is natural (בתכלס, מלא, ממש), a list of three when it fits, a punchline or a twist in the last line; no em-dashes.\nHesitations make it human — use them SPARINGLY, about one a line, never the same kind twice in a row: an \"אממ…\" at the very start, a restarted word (\"ש… שכל\", \"מ… מההתחלה\"), a short stutter on one word (\"נ… נתקעים\"), \"כאילו…\" while searching for a word, \"…\" for a thinking pause. Never a stutter on a name, a number or the punchline.\nFor every line also: \"beat\" = ONE acted physical moment tied to one word of the line, in English for a video model (a real nose scratch, two fingers on \"two\", mocking a stiff robot with both hands, rubbing the forehead, looking at their own hands, a dismissive flick of the wrist, pointing at the lens); \"keywords\" = 1-2 words of the line to colour in the captions.\nReturn JSON only: {\"lines\":[{\"say\":\"...\",\"beat\":\"...\",\"keywords\":[\"...\"]}]}",
  "prompt": "The topic: <what it is about, the twist at the end, who watches>. Four lines." }   // ≈ 17 credits
// → { lines: [ { say, beat, keywords } ] }
```

**Read it once yourself** — spoken Hebrew is the point. The example's line 2 came back "בתכלס זה שעות של לארגן חצובה…"
and became "בתכלס זה שעות. לסדר חצובה, לכוון תאורה, וכאילו… מלא טייקים." Colloquial forms stay ("איזה מילה" is how
people say it). **Lines of 6–9 seconds use Omni best**: it always makes and bills 10 seconds a take.

## 4. Shoot every line — Gemini Omni, a real restless person

One take a line from its start frame (line 1 the first frame, line 2 the second, and so on), all lines at once:

```jsonc
POST /v1/ai/video { "model": "gemini-omni-1.1-flash", "image_url": "<the line's frame>", "aspect_ratio": "9:16", "resolution": "720p",
  "prompt": "Raw, unedited footage <he> films <himself> on <his> phone. ONE single continuous take: the phone is propped on the desk a bit below <his> face, slightly tilted, static — no cuts, no zoom, no camera moves. Absolutely NO subtitles, NO captions, NO on-screen text: the words are only spoken aloud, never written anywhere. NO music.\n\nThe <man> in the image sits close to <his> phone and talks to <his> Instagram followers in fluent native Israeli Hebrew, at a natural quick pace, casual, like telling a friend something <he> just noticed while still thinking it through — not a presenter, not an ad. <He> says exactly this, and nothing else:\n\"<the line — AI written as איי איי>\"\nThe small hesitations written in the line (\"אממ\", a word started and repeated, the \"…\" pauses) are said naturally and briefly, the way people really talk, never exaggerated.\n\n<He> moves like a real, slightly restless person, NOT like a presenter or an AI avatar:\n- The hands are never frozen and almost never mirror each other: mostly ONE hand talks while the other stays on the desk or follows half a beat late.\n- Quick, small, messy gestures that come and go every second or two, with varied hand shapes: bunched fingertips, a quick point at the lens, a loose flick of the wrist, a hand rolling forward, an open palm thrown out and dropped. Some gestures start and are abandoned halfway; between them the hands drop back to the desk edge for a moment, then come up again.\n- The gestures land a little before or after the words, never exactly on the beat, and some have nothing to do with the words. A hand sometimes comes close to the lens fast and is motion-blurred.\n- The head is alive the whole time: small tilts, quick nods, a little shake, leaning in and back, a shoulder shrug. The eyes are mostly on the lens but glance away to the side for a moment when searching for a word, then come back.\n- The face keeps changing with the words: eyebrows up, a one-sided half-smirk, a quick frown, no fixed smile.\n- In this line: <the beat>.\nHands and arms with natural anatomy, five fingers each. The lips clearly form every word. After the last word <he> stops talking and reacts naturally for a moment (a small smile, a breath, a glance), then looks back at the lens.\n\nThe same face, the same build and the same clothes as in the image all the time. The same room and the same imperfect light as in the image. A real phone front-camera video, not a production: slightly wide lens, a little soft, visible noise in the shadows, the auto-exposure shifting slightly when a hand comes close, natural skin with pores and a little shine, no beautification, no colour grading. Ordinary room sound." }     // ≈ 392 credits a take (10 s) → output.url
```

What each part of the prompt fixed (measured against the creator's reel): the old "presenter" prompt left the hands frozen,
then moved both together slowly in one shape for seconds (hands mirroring 0.63, a repeating rhythm); "one hand talks,
abandoned gestures, loose timing" brought the mirroring to 0.24 and the rhythm to the creator's level; "phone propped, no
cuts, no subtitles" stops Omni from cutting angles and burning in text (it still does now and then — step 5). Omni speaks
the line in its own voice; that voice is thrown away (step 6) — only its body, face and lips are kept.

## 5. Watch every take — then look yourself

```jsonc
POST /v1/ai/text { "quality": "best", "json": true, "temperature": 0.2,
  "system": "You check one generated clip of a person talking to their phone camera, made from the start frame you also get. The line they should say and the one acted moment they should do are given. Answer JSON only:\n{\"text_on_screen\": true if ANY letters, subtitles, captions or a logo appear anywhere at any moment, \"face_same\": true if it is the same face as the start frame the whole time, \"hands_ok\": true if the hands look natural all the time (five fingers, no melting or extra fingers), \"beat_done\": true if the acted moment happens, \"frozen\": true if the hands stay still most of the time or both hands move together like a mirror, \"said\": \"the Hebrew words as you hear them\", \"real\": 1-10 how much it looks like a real person filming themselves (not a presenter, not an avatar), \"note\": \"one short line\"}",
  "prompt": "The line: <say>\nThe acted moment: <beat>",
  "media": [ { "url": "<the line's frame>", "type": "image" }, { "url": "<the take>", "type": "video" } ] }   // ≈ 8 credits a take
```

Keep a take with `text_on_screen: false`, the face the same, natural hands; shoot the line again otherwise. **Look at the
take yourself before you throw it away or keep it**: in the example the check rightly caught two takes with a word burned
into the shirt ("לכם", "תאורה") and one frozen take — and wrongly called a good take "head stretched". Repeated words in
Omni's own speech do not matter (its voice is replaced).

## 6. The voice — your clone, correct Hebrew

**Never Gemini's own voice, not even turned into your timbre**: speech-to-speech keeps its non-native Hebrew, and the owner
heard it at once twice ("the Hebrew here is bad") though every word transcribed right. Your clone reads the line — the
director once, then two quick re-reads of its text with one tag:

```jsonc
POST /v1/ai/voice { "text": "<say>", "voice_id": "<your voice_id>", "language_code": "he", "stability": 0.35, "timestamps": true,
  "mood": "casual, thinking out loud, talking to friends into the phone: quick, warm, natural, the small hesitations as written, not an ad",
  "previous_text": "<the line before>", "next_text": "<the line after>" }                      // → output.directed.tts (its niqqud)
POST /v1/ai/voice { "text": "[fast, casual, like talking to a friend] <output.directed.tts without its tags>", "voice_id": "<your voice_id>",
  "language_code": "he", "stability": 0.45, "prepare": false, "timestamps": true, … }          // ×2 · ≈ 11 credits a line for all three
POST /v1/speech/transcripts { "audio_url": "<each take>", "language_code": "he" }              // ≈ 1 — every word said?
```

Why the re-read: the director's own tags made a slower, more announcer-like read; one quick casual tag over its niqqud was
the most human in a blind test (only his real recording beat it). Keep a quick take with every word — the example's director
put the points where a voice slips (טֵייקִים, נִתְקָעִים, שַׂמְתֶּם).

## 7. Cut each take to its voice

HeyGen refuses audio and video whose lengths differ by more than 15 % — and Omni's take is 10 seconds while a line's voice
is 4–6. Find where Omni starts talking and keep that much of the take:

```jsonc
POST /v1/speech/transcripts { "audio_url": "<the take>", "language_code": "he" }                    // words[0].start (ms)
POST /v1/studio/convert { "video_url": "<the take>", "trim": { "start": <first word − 0.15>, "end": <start + the voice's length + 0.05> },
  "output": { "format": "mp4" } }                                                                     // ≈ 8 credits a line for both
```

**The last line gets 0.5 s more** (`+ 0.5` instead of `+ 0.05`): the reaction after the punchline stays in the video.

## 8. The lips

```jsonc
POST /v1/video/lipsync { "video_url": "<the cut take>", "audio_url": "<the chosen voice take>", "mode": "precision",
  "fit_to_audio": true, "keep_format": true,
  "consent": { "accepted": true, "subject": "self", "basis": "own", "locale": "he" } }   // ≈ 11 credits a second — the last line "fit_to_audio": false
```

**Check that the mouth really moved.** HeyGen once handed back a clip untouched — "completed", charged — ten times in a row
for one shot; a new take of that line worked at once. With `fit_to_audio: true` the result is exactly as long as the voice.

## 9. The jump cuts — one call

Every line from 0.12 s before its first word to 0.3 s after its last (the last line to its end) — **never past the end of
its lip-synced clip** — and a cut at any pause longer than 0.45 s inside a line (keep 0.18 s of it). The voice's own words
(`output.words` of the chosen take) are the clock:

```jsonc
POST /v1/studio/merge { "clips": [ { "url": "<line 1 lips>", "start": 0.04, "end": 4.6 }, { "url": "<line 2 lips>", "start": 0, "end": 5.81 }, … ],
  "transition": { "type": "none" }, "output": { "aspect_ratio": "9:16", "resolution": "1080" } }   // ≈ 26 credits
```

## 10. Captions, a punch-in on every other cut, a quiet bed, the credit — one render

```jsonc
POST /v1/ai/music { "prompt": "a light, warm lo-fi beat for a casual talking-to-camera video: soft keys, gentle drums, unobtrusive, no vocals, steady",
  "duration": <the video + 1>, "instrumental": true }                                   // ≈ 1 credit a second
POST /v1/studio/edit { "video_url": "<the merged video>",
  "words": [ { "text": "<word>", "start": <ms on the merged clock>, "end": <ms> }, … ],   // the voices' words, moved by each clip's place
  "zoom": [ { "start": <a clip's start>, "end": <its end>, "from": 1.12, "to": 1.12, "x": 0.5, "y": 0.33 }, … ],   // every other clip, the last at 1.0
  "captions": { "style": { "preset": "keyword-pop", "keywords": [ <the lines' keywords> ], "keyword_color": "#D0F808",
    "keyword_scale": 1.18, "position": "center", "animation": "pop", "max_lines": 1 } },
  "music": { "url": "<the bed>", "volume": 0.16, "normalize": false, "duck": false, "fade_in_ms": 300, "fade_out_ms": 900 },
  "texts": [ { "id": "credit", "text": "נערך עם *apihub.co.il*", "preset": "pill", "effect": "box",
    "style": { "y": 92.5, "size": 3.4, "weight": 800, "color": "#FFFFFF", "background": "#0B0B14E6", "accent_color": "#D0F808" },
    "start": 0, "duration": <the video> } ],
  "audio": { "normalize": true }, "hold_end": 0.3,
  "output": { "aspect_ratio": "9:16", "resolution": "1080", "quality": "high" } }       // ≈ 1.35 credits a second
```

**The words are the voice's, not a new transcript**: each line's words move by `clip start on the merged clock − the
clip's own start` — a word after the clip's end is dropped (the clip ended there). The hesitations stay in the captions
("אממ…", "וכאילו…") — they are part of the voice. `"style": "keyword-pop"` alone gives the look in yellow; the overrides
above make the key words lime and keep one line in the middle of the frame. The bed at 0.16 sits ≈ 17 dB under the voice
(`normalize: false`).

## What the example cost

The example: 4 lines, 20 seconds, the owner's photo and his own clone, made by this recipe on dev —
**4,184 credits**, the clone made before. **Omni is almost all of it** (≈ 392 a take, always 10
seconds): 9 takes for 4 lines.

| Step | Credits |
| --- | ---: |
| The two frames (three images) | 160 |
| The script | 17 |
| The shots: 9 Omni takes | 3531 |
| The take check (Gemini 3.1 Pro watches each) | 70 |
| The voice: 3 reads a line | 45 |
| The voice check (a Hebrew transcript a take) | 12 |
| Cutting each take to its voice | 34 |
| The lips (HeyGen Precision) | 242 |
| The jump cuts | 26 |
| The music bed | 20 |
| The render (20 s, 1080p) | 27 |
| **Total** | **4,184** |

**Cheaper:** lines of 8–9 seconds (fewer takes for the same minute), and one take a line unless the check fails — about
492 credits a line then.

## Tune it

The clothes and the room in `FRAME_PROMPT` · the pose · how many hesitations (`SCRIPT_BRIEF`: "about one a line") ·
the acted moment of each line · `stability` · the punch-in (1.12) · the bed's level · a woman: "she/her/herself" and
"woman" in `SHOT_PROMPT`, feminine forms in the script and a woman's clone.

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.
