Gemini Omni 1.2 Flash는 Google이 2026년 11월에 공개한 영상 생성·편집 모델입니다. POST /v1/videos/generations로 비동기 작업을 제출합니다. 이미지가 없으면 텍스트-투-비디오, 이미지 1장은 첫 프레임, 2장은 첫·마지막 프레임, 참조 이미지 1~3장, 또는 1~15초 영상을 넣으면 그 영상을 편집합니다. 720P / 1080P / 4K, 16:9 또는 9:16, 사운드 포함·보이는 워터마크 없음. 초당 과금이며 편집은 원본 초 수로 과금합니다.
빠른 시작
세 단계면 됩니다: 작업 제출 → 결과 조회 → 영상 링크 받기. YOUR_API_KEY를 내 키로 바꾸면 아래 명령을 그대로 실행할 수 있습니다.
1단계 · 제출(작업 ID를 바로 돌려줍니다, HTTP 202)
curl https://kovapi.com/v1/videos/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "gemini-omni-1.2-flash", "prompt": "비 오는 밤 네온 거리를 종이배가 떠내려가고, 노란 우비를 입은 아이가 웃으며 뒤쫓는다", "duration": 10, "resolution": "720P", "size": "16:9"}'응답(HTTP 202)
{
"id": "img_5c2e8f1a9b3d7e6f0a4c8b2d",
"object": "video.generation.job",
"status": "queued",
"created": 1791281400,
"model": "gemini-omni-1.2-flash"
}2단계 · status가 succeeded 또는 failed가 될 때까지 5~10초마다 조회
curl https://kovapi.com/v1/videos/jobs/img_5c2e8f1a9b3d7e6f0a4c8b2d \ -H "Authorization: Bearer YOUR_API_KEY"
성공했을 때의 응답
{
"id": "img_5c2e8f1a9b3d7e6f0a4c8b2d",
"object": "video.generation.job",
"status": "succeeded",
"created": 1791281400,
"model": "gemini-omni-1.2-flash",
"data": [
{"url": "https://img.kovapi.com/i/8c1f0e5d2b7a49e3a6d0c4f1b9e2a7d5.mp4"}
],
"usage": {"clips": 1, "model": "gemini-omni-1.2-flash"}
}3단계 · data[0].url이 결과 영상(MP4)입니다. 7일 동안 보관되므로 더 오래 쓰려면 내 저장소에 내려받아 두세요.
전체 예제(Python: 제출 → 대기 → 로컬에 저장)
import time
import requests
BASE = "https://kovapi.com/v1"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}
# 1. 제출
job = requests.post(f"{BASE}/videos/generations", headers=HEADERS, json={
"model": "gemini-omni-1.2-flash",
"prompt": "비 오는 밤 네온 거리를 종이배가 떠내려가고, 노란 우비를 입은 아이가 웃으며 뒤쫓는다",
"duration": 10,
"resolution": "720P",
"size": "16:9",
}).json()
if "error" in job:
raise SystemExit(job["error"]["message"])
# 2. 10초마다 조회, 최대 1시간까지 대기
deadline = time.time() + 3600
while job["status"] not in ("succeeded", "failed") and time.time() < deadline:
time.sleep(10)
job = requests.get(f"{BASE}/videos/jobs/{job['id']}", headers=HEADERS).json()
# 3. 영상 내려받기
if job["status"] == "succeeded":
url = job["data"][0]["url"]
with open("gemini-omni-1.2-flash.mp4", "wb") as f:
f.write(requests.get(url).content)
print("saved", url)
elif job["status"] == "failed":
print("failed:", job["error"]["code"], job["error"]["message"])
else:
print("still", job["status"], job["id"])대기 중일 때는 조회 결과에 queue_position(앞에 있는 작업 수)과 eta_seconds(예상 대기 시간)도 함께 옵니다. 프로그램에 정해 둔 대기 시간을 넘겨도 다시 제출하지 마세요. 작업은 그대로 남아 있으니 나중에 같은 작업 ID로 이어서 조회하면 됩니다.
인증
Authorization: Bearer YOUR_API_KEY Content-Type: application/json
콘솔에서 API 키를 만들면 시작할 수 있습니다.
사양 한눈에 보기
| 길이 | 3~15초(1초 단위, 기본 10초) · 프레임 지정 3~10초 · 편집은 원본 길이(1~15초) |
| 해상도 | 720P / 1080P / 4K |
| 화면 비율 | 16:9 / 9:16 |
| 참조 이미지 | 첫 프레임 1장 · 첫·마지막 2장 · 참조 1~3장 · 편집 시 참조 최대 5장 |
| 영상 편집 | 영상 편집: 원본 영상 1개, 1~15초, mp4 / mov, 50MB까지 · 원본 초 수로 과금 |
| 참조 오디오 | 지원하지 않음 |
| 소리 | 항상 사운드 포함(대사·음악·효과음은 프롬프트에 적습니다). 끌 수 없습니다(audio: false는 거절) |
| 프롬프트 길이 | 최대 20,000자(중국어와 영어 모두 글자 수) |
| 과금 방식 | 초당: 선택한 해상도의 초당 단가 × 길이(편집은 원본 초 수) |
요청 파라미터
POST /v1/videos/generations의 요청 본문(JSON):
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
| model | string | 예 | 모델 ID: gemini-omni-1.2-flash. |
| prompt | string | 예 | 영상 내용·카메라·동작·소리 설명, 최대 20,000자(중국어와 영어 모두 글자 수). 여러 참조 이미지는 @Image1 / @Image2로 지정합니다. 편집은 바꿀 내용을 적습니다. 예: "밤으로 바꾸고 나머지는 그대로". negative_prompt는 지원하지 않으니 원하지 않는 내용은 프롬프트에 직접 적으세요. |
| duration | integer | 아니오 | 길이: 3~15초 정수(기본값 10). seconds로도 쓸 수 있습니다. 프레임 지정 모드는 3~10초. 영상 편집에서는 넣지 않으며 결과는 원본 길이를 따릅니다. 초당 과금, 아래 "가격" 참고. |
| resolution | string | 아니오 | 해상도: 720P(기본값) / 1080P / 4K(1080P와 4K는 공식 업스케일, 4K 세로는 2160×3840). 720p, 1080p, 4k, 2160p도 받습니다. 360P는 지원하지 않습니다. |
| size | string | 아니오 | 화면 비율: 16:9(기본값) / 9:16. aspect_ratio로도 쓸 수 있습니다. 다른 비율은 거절됩니다. 영상 편집에서 생략하면 원본의 방향을 따릅니다. |
| images | array | 아니오 | 여러 이미지(장당 16MB까지). 2~3장은 기본적으로 참조 이미지(최대 3장), image_role=first_frame이면 2장이 첫·마지막 프레임, 영상 편집은 참조 이미지 최대 5장. image_urls와 image_with_roles([{"url": ..., "role": "first_frame" | "last_frame" | "reference"}])도 받습니다. 상한을 넘으면 잘라내지 않고 거절합니다. 이미지 1장(공개 URL, data: URI 또는 base64). 기본은 첫 프레임(3~10초)이며 image_role=reference면 참조 이미지가 됩니다. first_frame_image와 last_frame_image도 받습니다. |
| image_role | string | 아니오 | first_frame(첫 프레임 / 첫·마지막, 3~10초) 또는 reference(참조 1~3장). 생략하면 1장은 첫 프레임, 2~3장은 참조입니다. 다른 일반적인 표기 first_frame_image, last_frame_image, image_urls, image_with_roles, omni_reference_task_type도 받습니다. |
| video_urls | array | 아니오 | 영상 편집: 1~15초 영상 하나(mp4 / mov, 50MB까지. 공개 링크, data:video/mp4;base64,... 또는 Playground 업로드 링크). video_url / video_references로도 쓸 수 있습니다. 결과는 원본 길이를 따르며 원본 초 수로 과금합니다. 마지막 정수 초를 넘는 부분은 잘라냅니다(4.5초는 4초로 편집·과금). 프레임 지정과 함께 쓸 수 없고 이어 만들기(extend)는 지원하지 않습니다. |
| audio | boolean | 아니오 | 이 모델은 항상 사운드를 생성합니다(대사·음악·효과음은 프롬프트에 적습니다). 이 매개변수는 생략할 수 있습니다(false는 거절됩니다). |
| callback_url | string | 아니오 | 작업이 끝나면 결과를 보낼 주소. 아래 웹훅 부분을 보세요. |
| n | integer | 아니오 | 작업 하나는 영상 1개를 만들므로 넣지 않아도 됩니다. 1보다 큰 값을 넣어도 영상은 1개만 나오지만, 제출할 때 n개 분의 크레딧이 예약되고 초과분은 작업이 끝날 때 돌아옵니다. |
그 밖의 필드(seed, negative_prompt, fps, watermark 등)는 전달되지 않으며 가격에도 영향을 주지 않습니다. 결과는 항상 MP4이며 url로 돌려줍니다.
가격
초당 과금: 비용 = 선택한 해상도의 초당 단가 × 길이. 영상 편집은 원본 초 수로 과금합니다(마지막 정수 초를 넘는 부분은 잘라내고 과금하지 않습니다). 참조 이미지는 무료입니다. 이 금액을 제출 시 선결제하고 성공하면 같은 금액으로 확정하며, 실패하면 전액 환불합니다. 1크레딧 = $0.005.
| 해상도 | 초당 크레딧 | 초당 가격(USD) | 10초 영상 1개 | 8초 원본 편집 |
|---|---|---|---|---|
| 720P | 7 | $0.035 | $0.35 | $0.28 |
| 1080P | 10 | $0.05 | $0.50 | $0.40 |
| 4K | 20 | $0.10 | $1.00 | $0.80 |
참조 소재
- 첫 프레임 / 첫·마지막 프레임:
image에 1장이면 첫 프레임,images에 2장과image_role: first_frame이면 첫·마지막 프레임입니다. 최대 10초. 이미지의 가로세로를size에 맞추세요. - 참조 이미지:
images에 1~3장과image_role: reference(2~3장이면 생략해도 참조). 이미지 속 인물·사물·배경이 프레임이 아니라 영상에 등장합니다. 프롬프트에서 @Image1 / @Image2로 지정할 수 있습니다. - 영상 편집:
video_urls에 1~15초 영상 하나를 넣고 프롬프트에 바꿀 내용을 적습니다. 예: "달빛 비치는 밤으로 바꾸고 나머지는 그대로". 참조 이미지를 최대 5장까지 함께 넣을 수 있습니다("인물을 @Image1의 사람으로 바꿔"). 제출 시 원본을 내려받아 길이를 재며, 읽을 수 없거나 1초 미만·15초 초과면 400을 돌려주고 과금하지 않습니다. - 아직 지원하지 않음: 360P, 이어 만들기(extend), 참조 영상 / 참조 오디오 입력, negative_prompt(원하지 않는 내용은 프롬프트에 직접 적으세요).
- 이미지는 각각 공개 이미지 URL,
data:URI, base64 중 하나로 보낼 수 있으며 한 장당 16MB 이하입니다. 여러 장은images에 배열로 넣으세요. 제출할 때 당사가 이미지를 먼저 저장한 뒤 작업을 대기열에 넣습니다. 읽을 수 없는 이미지가 있으면 400으로 거절되고message에 몇 번째 이미지인지 적혀 있으며, 과금되지 않습니다. - 당사가 저장한 참조 소재와 결과 영상은 모두 7일 동안 보관됩니다.
영상 편집: 장면을 바꾸고 참조 이미지의 인물로 교체
curl https://kovapi.com/v1/videos/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "gemini-omni-1.2-flash", "prompt": "달빛 비치는 밤으로 바꾸고 가운데 인물을 @Image1의 사람으로 바꿔, 나머지는 그대로", "video_urls": ["https://example.com/clip-8s.mp4"], "images": ["https://example.com/person.png"], "resolution": "720P"}'결과는 원본 길이를 따릅니다. 원본이 8초면 8초로 과금하며 참조 이미지는 무료입니다.
작업 상태와 응답 필드
GET /v1/videos/jobs/{id}는 아래 상태를 돌려줍니다. 각 필드의 설명은 비동기 작업에 있습니다. 5~10초마다 조회하거나, 아래의 웹훅으로 결과를 받으세요. 조회는 무료이며, 같은 계정의 어느 키로든 조회할 수 있습니다.
| 상태 | 의미 |
|---|---|
| queued | 대기 중. queue_position(앞에 있는 작업 수)과 eta_seconds(예상 대기 시간)가 함께 옵니다. |
| processing | 생성 중. |
| succeeded | 완료. 결과는 data[0].url, 과금 내역은 usage에 있습니다. |
| failed | 실패. 사유는 error에 있고, 예약된 크레딧은 전액 환불됩니다. |
processing이queued로 돌아갈 때가 있습니다. 예를 들어 서비스가 붐빌 때, 완성된 영상을 다시 가져오는 중일 때, 서비스가 재시작된 뒤입니다. 작업을 끝내지 못하면 게이트웨이가 자동으로 다시 만들 수 있습니다. 몇 번을 재시도하든 작업 하나에 한 번만 과금됩니다.- 한 계정은 최대 50개 작업을 동시에 생성하며, 그보다 많은 작업은 제출 순서대로 대기합니다. 15분이 지나도 시작되지 않은 작업은 자동으로 실패 처리되고 전액 환불됩니다. 작업 기록은 3일, 영상 링크는 7일 동안 보관됩니다.
생성 시간
저희 테스트: 720P 3~6초 약 1분, 1080P 13초 약 2.5분, 4K 약 3분, 편집 약 1.5분. 대기열이 길면 더 걸리며 최대 20분을 기다린 뒤 넘으면 전액 환불합니다.
오류와 환불
제출 단계의 오류는 HTTP 4xx / 5xx로 바로 돌아오며, 작업은 만들어지지 않고 과금되지 않습니다. 작업이 접수된 뒤의 실패는 작업 조회 결과로 알려 주며, 예약된 크레딧은 전액 환불됩니다. 전체 코드는 오류 코드에 있습니다.
제출할 때 돌아오는 오류
| HTTP | code | 원인 | 조치 |
|---|---|---|---|
| 400 | invalid_request | 파라미터가 올바르지 않습니다. 길이, 해상도, 화면 비율 또는 참조 소재 수가 이 모델의 허용 범위를 벗어났거나, 프롬프트가 너무 길거나, 참조 이미지나 참조 영상을 읽을 수 없거나, 항상 소리가 포함되는 모델에 audio: false를 보낸 경우 등입니다. 구체적인 원인은 message에 적혀 있습니다. | message에 적힌 대로 고친 뒤 다시 제출하세요. |
| 400 | invalid_source_video | 원본 영상을 받지 못했습니다: 길이를 읽을 수 없거나, 1초 미만·15초 초과이거나, 파일이 손상되었습니다. | 재생 가능한 1~15초 mp4 / mov로 바꿔 다시 제출하세요. 이번 요청은 과금되지 않았습니다. |
| 400 | invalid_callback_url | callback_url이 공개된 http(s) 주소가 아니거나 2000자를 넘습니다. | 인터넷에서 접근할 수 있는 주소를 쓰세요. |
| 400 | model_not_found | 모델 ID의 철자가 틀렸거나, model이 없거나, 이 엔드포인트에서 쓸 수 없는 모델입니다(예: 이미지 엔드포인트에 채팅 모델을 지정한 경우). | GET /v1/models 또는 API 레퍼런스에 있는 모델 ID를 쓰세요. |
| 401 | invalid_api_key | 키가 없거나, 삭제되었거나, 비활성화되었습니다. 계정이 비활성화된 경우에도 나옵니다. | 콘솔의 「API Keys」 페이지에서 이 키를 확인하세요. |
| 402 | insufficient_quota | 이 요청의 크레딧을 예약하기에 잔액이 부족합니다. 게이트웨이는 요청에 들 수 있는 최대 비용을 먼저 예약하므로, 동시 호출이 몰릴 때도 이 오류가 날 수 있습니다. | 동시 호출이 몰린 경우라면 몇 초 기다린 뒤 다시 시도하고, 그렇지 않으면 충전하세요. |
| 429 | rate_limit_exceeded | 이 키에 설정한 분당 요청 수를 넘었습니다(최근 60초 기준). Retry-After 헤더는 붙지 않습니다. | 몇 초 기다린 뒤 다시 시도하거나, 콘솔에서 이 키의 한도를 올리세요. |
| 503 | model_maintenance | 모델이 점검 중이라 요청을 받지 않습니다. 점검 중에는 다른 모델이 대신 답변하지도 않습니다. | 점검이 끝나면 다시 시도하세요. 진행 상황은 서비스 상태에서 볼 수 있습니다. |
| 503 | service_unavailable | 참조 소재 저장 실패처럼 당사 측에서 일시적인 오류가 났습니다. 작업은 만들어지지 않았고 과금되지도 않았습니다. | 잠시 후 다시 시도하세요. |
작업 실패(status가 failed)
| code | 언제 나오나요 | 조치 |
|---|---|---|
| content_policy | 프롬프트나 참조 이미지가 모델 제공사의 콘텐츠 심사를 통과하지 못했습니다. | 프롬프트를 고쳐 쓰거나 참조 소재를 바꾼 뒤 다시 제출하세요. 같은 입력은 다시 거부됩니다. |
| invalid_request | 모델 제공사가 이 조합(예: 모드와 해상도)을 받지 않습니다. 이유는 message에 적혀 있습니다. | message에 적힌 대로 파라미터를 조정한 뒤 다시 제출하세요. |
| wait_timeout | 영상: 120분 안에 결과가 나오지 않아 시간 초과로 처리하고 크레딧을 전액 환불했습니다. 이후 생성이 완료되면 영상은 무료로 제공합니다. | 다시 제출하세요. |
| upstream_error | 그 밖의 실패: 자동 재시도 후에도 실패했거나, 15분 동안 기다려도 시작되지 않았거나, 업스트림이 이유 없이 거부한 경우 등입니다. 구체적인 내용은 message에 있습니다. | 다시 제출하면 대개 성공합니다. |
message의 문구가 아니라 code로 판단하세요. 모르는 code가 오거나 code가 없으면 upstream_error로 처리하면 됩니다. 다시 제출하면 대개 성공합니다. 실패한 작업은 모두 전액 환불됩니다.
조회 대신 웹훅으로 받기
제출할 때 callback_url을 넣으면 작업이 끝나는 즉시(성공이든 실패든) 게이트웨이가 조회 엔드포인트와 똑같은 결과를 그 URL로 보냅니다. 서명이 포함되며, 전송에 실패하면 자동으로 재시도합니다. 콘솔의 「설정 → 웹훅」에서 계정 전체에 쓸 주소를 지정할 수도 있습니다. 웹훅 문서 →
curl https://kovapi.com/v1/videos/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "gemini-omni-1.2-flash", "prompt": "비 오는 밤 네온 거리를 종이배가 떠내려가고, 노란 우비를 입은 아이가 웃으며 뒤쫓는다", "duration": 10, "resolution": "720P", "size": "16:9", "callback_url": "https://your-domain.com/webhook"}'