gemini-omni-1-2
Gemini Omni 1.2 on reAPI — 3–15 second video with sound from text, images or frames, plus editing and extending a clip, at 360p to 4K.
Google's Gemini Omni 1.2 Flash, live on reAPI. One model id,
gemini-omni-1-2, covers text to video, image to video, first and last
frame interpolation, subject references, editing a clip and extending one.
Every clip has sound and renders at 360p, 720p, 1080p or 4k; a new
clip runs 3–15 seconds, and an extension returns its source followed by up
to 10 new seconds. See current pricing on the
model page.
Quick example
curl https://reapi.ai/api/v1/videos/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-omni-1-2",
"prompt": "A glass marble rolls fast along a wooden chain-reaction track through a sunlit workshop, one continuous smooth tracking shot. No text, no logos.",
"resolution": "720p",
"duration": 8,
"aspect_ratio": "16:9"
}'import requests
response = requests.post(
"https://reapi.ai/api/v1/videos/generations",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"model": "gemini-omni-1-2",
"prompt": "A glass marble rolls fast along a wooden chain-reaction track through a sunlit workshop, one continuous smooth tracking shot. No text, no logos.",
"resolution": "720p",
"duration": 8,
"aspect_ratio": "16:9",
},
timeout=60,
)
response.raise_for_status()
task_id = response.json()["id"]const response = await fetch('https://reapi.ai/api/v1/videos/generations', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'gemini-omni-1-2',
prompt:
'A glass marble rolls fast along a wooden chain-reaction track through a sunlit workshop, one continuous smooth tracking shot. No text, no logos.',
resolution: '720p',
duration: 8,
aspect_ratio: '16:9',
}),
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const { id: taskId } = await response.json();package main
import (
"encoding/json"
"fmt"
"net/http"
"strings"
"time"
)
func main() {
body := strings.NewReader(`{
"model": "gemini-omni-1-2",
"prompt": "A glass marble rolls fast along a wooden chain-reaction track through a sunlit workshop, one continuous smooth tracking shot. No text, no logos.",
"resolution": "720p",
"duration": 8,
"aspect_ratio": "16:9"
}`)
req, err := http.NewRequest("POST", "https://reapi.ai/api/v1/videos/generations", body)
if err != nil { panic(err) }
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 60 * time.Second}
res, err := client.Do(req)
if err != nil { panic(err) }
defer res.Body.Close()
var task struct { ID string `json:"id"` }
if err := json.NewDecoder(res.Body).Decode(&task); err != nil { panic(err) }
fmt.Println(task.ID)
}Authentication
Every call needs a Bearer token. Generate keys at reapi.ai/settings/apikeys.
Authorization: Bearer YOUR_API_KEYEndpoint
POST /api/v1/videos/generations
GET /api/v1/tasks/{id}Submission is async. The POST returns a task id right away; poll the task
endpoint until status is completed or failed. Polling does not consume
credits.
Request body
| Field | Type | Default | Notes |
|---|---|---|---|
model | string | — | gemini-omni-1-2. Required. |
prompt | string | — | Required in every mode: the shot, the change for an edit, or what happens next for an extension. Describe the sound too; put negative instructions here. |
duration | integer | 10 | 3–15 seconds. At most 10 with first and last frames and for an extension (the added part). Ignored by an edit, which keeps the source length. |
resolution | string | 720p | 360p / 720p / 1080p / 4k (2160p means 4k), case-insensitive. 1080p and 4k are upsampled. |
aspect_ratio | string | 16:9 | 16:9 or 9:16. |
image_urls | string[] | — | One image is the start frame; several are subject references. Up to 10 images in total, frames and role images included. |
first_frame_image | string | — | The clip opens on this image; with last_frame_image the model interpolates between the two. |
last_frame_image | string | — | The clip ends on this image. Needs a first frame. |
image_with_roles | object[] | — | {"url", "role"} with role first_frame, last_frame, or any other role for a reference. Give frames this way or with the two frame fields, not both. |
video_urls | string[] | — | One clip of at most 15 seconds to edit or extend. |
omni_reference_task_type | string | auto | auto / edit / extend / reference / text_to_video / image_to_video / reference_to_video. |
extend_from_task_id | string | — | The id of one of your completed gemini-omni-1-2 tasks, to edit or extend its video without uploading it. |
Every clip comes with sound; there is no sound switch. There is no
negative_prompt, seed or audio input. Unknown fields are refused rather
than ignored.
Checked by reAPI before anything is charged:
- every media field is a public HTTP(S) URL — base64 and
data:URIs are rejected resolutionis one of the four values, anddurationis a positive whole number- the video to edit or extend can be measured (its length sets the bill — see Pricing)
extend_from_task_idnames a completedgemini-omni-1-2task of yours
Every other rule on this page — image counts, frame combinations, mode
limits, source length — is checked by the model when the task starts. A
request that breaks one ends as a failed task with code 80007 and the exact
reason, and is refunded in full.
Modes
| Mode | How to select it |
|---|---|
| Text to video | No images and no video. |
| Image to video | One image in image_urls, or a first frame. |
| First and last frame | first_frame_image and last_frame_image, or the two roles. At most 10 seconds. |
| References | Several images in image_urls, or reference roles; omni_reference_task_type: "reference" to be explicit. |
| Edit | A video in video_urls or extend_from_task_id; auto or edit. |
| Extend | A video as above and omni_reference_task_type: "extend". Adds up to 10 seconds. |
A video input edits unless you ask for extend; with a video, reference,
text_to_video, image_to_video and reference_to_video are refused.
Google's guide documents up to 6 subject reference images (up to 3 per
character, for up to 2 characters).
First and last frame
{
"model": "gemini-omni-1-2",
"prompt": "Smooth transition, the camera slowly pushes in.",
"first_frame_image": "https://example.com/start.jpg",
"last_frame_image": "https://example.com/end.jpg",
"duration": 8
}Edit
{
"model": "gemini-omni-1-2",
"prompt": "Make the violin invisible. Keep everything else the same.",
"video_urls": ["https://example.com/clip.mp4"]
}The edit keeps the source length; duration has no effect. Short, specific
instructions work best; for a local change add "Keep everything else the
same".
Extend an earlier task
{
"model": "gemini-omni-1-2",
"prompt": "The camera keeps panning across the mountains.",
"extend_from_task_id": "task_018f5a3a1b6e7d9f8c2b4d6e8f0a2c4e",
"omni_reference_task_type": "extend",
"duration": 8
}The result contains the original followed by the new part. Only your own
completed gemini-omni-1-2 tasks can be named, and a task created from the
website playground can be named only from the playground. To extend your own
clip, send it in video_urls instead.
Troubleshooting
| Failure | What it means | What to do |
|---|---|---|
Synchronous 400 (code 30002) | resolution or duration is not a priced value, or the input video's length could not be read | Use one of the four resolutions and a whole number of seconds; pass a public MP4 or MOV URL. Nothing was charged |
Synchronous 404 (code 40001) | extend_from_task_id is not one of your tasks | Check the task id. Nothing was charged |
Synchronous 400 (code 20003) | The source task is not a completed gemini-omni-1-2 task | Wait until it completes, or pick another task. Nothing was charged |
Task fails with code 80007 | A model rule was broken: two frames over 10 seconds, a source over 15 seconds, too many images, an unknown field, … | The message names the field. Fully refunded |
Task fails with code 80006 | The prompt or media was rejected by content review | Fully refunded. Revise the prompt or inputs |
402 on submit | Not enough credits for the reserve | Top up, or lower duration or resolution |
Task stays processing | Generation takes a minute or more | Keep polling; a task that can never finish is failed and refunded automatically |
No data: URIs. reAPI rejects base64 inputs platform-wide — every URL
field must be a public HTTP(S) URL. Upload to your own object storage and pass
the URL.
Response envelope
{
"id": "task_018f5a3a1b6e7d9f8c2b4d6e8f0a2c4e",
"model": "gemini-omni-1-2",
"status": "completed",
"created_at": 1789689600,
"output": {
"video_urls": ["https://.../0.mp4"]
},
"error": null
}Poll GET /api/v1/tasks/{id} (see the Tasks reference)
until status === "completed", then read output.video_urls. A failed task
carries error.code and error.message; see the
errors catalog. Every video carries Google's invisible
SynthID watermark.
Pricing
Gemini Omni 1.2 bills per second, at a rate set by the resolution:
credits = ceil(per_second_rate × billable_seconds × 1000) 1 credit = $0.001| Request | billable_seconds |
|---|---|
| Text, image, frames, references | duration (default 10) |
| Edit | source + source / 8 |
| Extend | added seconds + source / 8 |
source is the input video's picture length, measured by reAPI when the
request is accepted and rounded up to whole seconds; the eighth covers
reading the input video. At any resolution, editing a 6.2-second clip bills
7 + 7/8 = 7.875 seconds, and extending an 8-second clip by 4 seconds bills
4 + 1 = 5 seconds. Failed tasks are refunded in full.
Live per-second rates for each resolution are on the model page.
Tips
- Describe subject, place, camera move, light and sound; the clip's audio follows the prompt.
- The model likes to cut between shots; ask for "a single continuous shot" when you need one.
- Draft at
360p, then render the shot you keep at1080por4kwith the same request. - For an edit, change one thing at a time and say what must stay the same.
- English prompts are fully supported; other languages are not evaluated by Google.