Dokümantasyon

Dokümantasyon

Video oluşturma

Google'ın Veo 3.1 ailesiyle metinden videoya ve görüntüden videoya üretim. İki API biçimi vardır: klip hazır olana kadar bekleyen tek adımlı senkron uç nokta ve üretim iş yükleri için bir gönderme ve sorgulama asenkron çifti.

Uç noktalar: POST /v1/video/generations (senkron, önce ele alınmıştır) ve POST /v1/videos + GET /v1/videos/{id} (asenkron, üretim için önerilir). Üretim, modele ve süreye bağlı olarak 30 saniyeden birkaç dakikaya kadar sürer — senkron uç nokta için istemci zaman aşımını yüksek ayarlayın (600s güvenlidir).

Metinden videoya

Bir prompt gönderin ve bir model seçin. aspect_ratio isteğe bağlıdır.

import requests

resp = requests.post(
    "https://api.kunavo.com/v1/video/generations",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "veo-3",
        "prompt": "a cinematic dolly-in on a red origami crane unfolding, soft light",
        "aspect_ratio": "16:9",
    },
    timeout=600,  # video generation can take minutes
)
print(resp.json()["data"][0]["url"])

duration (saniye cinsinden), saniye başına ücretlendirilen modellerde, yani Seedance modellerinde ve Wan 2.7'de klip uzunluğunu belirler. Veo modelleri bu değeri yok sayar; her Veo klibi 8 saniyedir ve video başına ücretlendirilir.

# The models billed per second take a clip length: here 5 seconds of
# Seedance 2. Leave "duration" out and these models make a 5-second clip.
resp = requests.post(
    "https://api.kunavo.com/v1/video/generations",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "seedance-2",
        "prompt": "a paper crane unfolds into a flock of birds over a city at dawn",
        "duration": 5,
        "aspect_ratio": "16:9",
    },
    timeout=600,
)
print(resp.json()["data"][0]["url"])

Görüntüden videoya

Bir image_url ekleyin; Veo görüntüden animasyon üretir — varsayılan olarak sabit görüntü videonun ilk karesi olur.

# Image-to-video: animate a still image. The source image can be an
# https URL, or inline base64 — Kunavo hosts it for the model automatically.
resp = requests.post(
    "https://api.kunavo.com/v1/video/generations",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "veo-3",
        "prompt": "the crane gently lifts off the desk",
        "image_url": "https://your-cdn.com/source.png",
    },
    timeout=600,
)
print(resp.json()["data"][0]["url"])
image_url, bir https:// URL'sini veya satır içi data: base64 URI'sini kabul eder. Model çalışmadan önce base64 otomatik olarak çözülür ve Kunavo'nun CDN'inde barındırılır.

İlk kare, son kare ve referanslar

image_mode, Veo'nun görüntüleri nasıl kullanacağını belirler. Birden fazla görüntü göndermek için image_urls (dizi) verin.

  • frame (varsayılan) — tek görüntü ilk kare olur; iki görüntü ilk ve son kare olur ve Veo aralarındaki geçişi üretir.
  • reference — en fazla üç görüntü, stil ve konu referansı olarak kullanılır. Görüntüler görsel tarzı yönlendirir ancak kare olarak videoda yer almaz.
# First + last frame: pass two images and Veo fills in the motion.
resp = requests.post(
    "https://api.kunavo.com/v1/video/generations",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "veo-3",
        "prompt": "a smooth transition between the two poses",
        "image_urls": [
            "https://your-cdn.com/first.png",
            "https://your-cdn.com/last.png",
        ],
        "image_mode": "frame",
    },
    timeout=600,
)

Kaynak kareyi yükleme

Yalnızca yerel bir dosyanız varsa, dosyayı bir kez POST /v1/files üzerinden yükleyin ve döndürülen kalıcı URL'yi yeniden kullanın.

# No public URL? Upload the still first, then animate it.
with open("frame.png", "rb") as f:
    up = requests.post(
        "https://api.kunavo.com/v1/files",
        headers={"Authorization": f"Bearer {API_KEY}"},
        files={"file": f},
    ).json()

resp = requests.post(
    "https://api.kunavo.com/v1/video/generations",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "veo-3",
        "prompt": "slow push-in, volumetric light",
        "image_url": up["url"],
    },
    timeout=600,
)

Parametreler

ParametreTürNotlar
modeldize (zorunlu)/v1/models içinden bir video modeli kısa adı.
promptdize (zorunlu)Çekimin metin açıklaması.
image_urlstringGörüntüden videoya için tek kaynak görüntü. URL veya data: URI.
image_urlsstring[]Birden fazla kaynak görüntü (Veo). image_url değerine göre önceliklidir.
image_modestringVeo: "frame" (varsayılan — ilk/son kare) veya "reference" (stil referansları).
durationintSaniye başına ücretlendirilen modellerde saniye cinsinden klip uzunluğu; belirtilmediğinde 5: Seedance 2, Seedance 2 Fast ve Seedance 2.0 Mini için 4–15, Seedance 2.5 için 4–30, Wan 2.7 için 2–15 geçerlidir. Bir modelin aralığı dışındaki uzunluk 400 hatasıyla reddedilir. Veo bu değeri yok sayar: her Veo klibi 8 saniyedir.
aspect_ratiostringÖrn. "16:9", "9:16", "1:1".
resolutionstringModelin kalite katmanları sunduğu yerlerde — ör. "720p", "1080p".
inputobjectAlternatif kullanım — aşağıya bakın Raw input.

Ham girdi için geçiş seçeneği

Saniye başına ücretlendirilen modellerde input, bağdaştırıcımızın oluşturacağı girdinin yerine, olduğu gibi üst akışa gönderilir. Veo modelleri bu değeri yok sayar.

Fiyatı belirleyen alanlar istisnadır: resolution her zaman modelin düzeylerinden biri olarak gönderilir (alan belirtilmezse veya değer bu düzeylerden biri değilse varsayılan düzey kullanılır); duration ise modelin aralığındaki tam sayı bir saniye değeri olmalıdır (diğer tüm değerler 400 hatasıyla reddedilir; alan belirtilmezse 5 gönderilir). input ayarlandığında isteğin kendi resolution ve duration alanları okunmaz.

Video modelleri

Kısa adSağlayıcıNotlar
veo-3GoogleVeo 3.1 Fast — Quality'den daha hızlı ve daha ucuz, yerleşik ses.
veo-3-qualityGoogleVeo 3.1 Quality — en yüksek doğruluk.
veo-3-liteGoogleVeo 3.1 Lite — önizlemeler için ekonomik katman.
seedance-2-5ByteDanceSeedance 2.5 — 30 saniyeye kadar klipler, çok modlu referanslar, saniye başına faturalandırma.
seedance-2ByteDanceSeedance 2 — çoklu çekim tutarlılığı, 1080p'ye kadar çözünürlük, saniye başına faturalandırma.
seedance-2-fastByteDanceSeedance 2 Fast — ekonomik katman, 720p'ye kadar çözünürlük, saniye başına faturalandırma.
seedance-2-miniByteDanceSeedance 2.0 Mini — en ucuz katman, yalnızca 480p/720p, taslaklar ve yüksek hacim için.
wan-2-7AlibabaWan 2.7 — sinematik metinden videoya üretim, saniye başına faturalandırma.

Güncel liste ve model başına fiyatlandırma için her zaman /models adresini kontrol edin.

Gecikme ve zaman aşımları

  • Kunavo, 504 döndürmeden önce üst akış görevini 540 saniyeye kadar sorgular.
  • Hızlı katmanlar (Veo 3.1 Fast / Lite): genellikle 30–90 sn.
  • Quality katmanları ve daha uzun süreler: 2–5 dakika.
  • HTTP istemcinizin zaman aşımını en az 600s olarak ayarlayın.
  • Kararsız ağlarda veya mobil istemcilerde bunun yerine asenkron API'yi tercih edin — gönderim saniyeler içinde döner ve sonucu sorgulayabilirsiniz.

Eşzamansız API (gönderim + yoklama)

Uç noktalar: POST /v1/videos + GET /v1/videos/{id}. Döndürdükleri görev nesnesi, OpenAI'ın video nesnesindeki alan adlarını ve durum değerlerini kullanır ve klibin URL'sini içeren output alanını ekler. İstek, yukarıdaki parametreleri içeren bir JSON gövdesidir.

Yukarıdaki senkron uç nokta, HTTP bağlantısını dokuz dakikaya kadar açık tutar — tek seferlik betikler için kullanışlıdır ancak mobil cihazlarda güvenilir değildir ve sunucuda verimsizdir. Asenkron çift hemen bir vid_* kimliği döndürür; GET /v1/videos/{id}, status değeri completed veya failed olana kadar sorgulanır. Modeller, fiyatlandırma ve arşivlenmiş URL'ler aynıdır.

import requests, time

# 1. Submit — returns immediately with a task id. No long-lived connection.
submit = requests.post(
    "https://api.kunavo.com/v1/videos",
    headers={
        "Authorization": f"Bearer {API_KEY}",
        # Optional: retrying with the same key inside ~24h returns the
        # original task rather than submitting again.
        "Idempotency-Key": "my-task-uuid",
    },
    json={
        "model": "veo-3",
        "prompt": "a cinematic dolly-in on a red origami crane",
        "aspect_ratio": "16:9",
    },
    timeout=60,
).json()

task_id = submit["id"]              # "vid_abc..."
status  = submit["status"]          # "queued"

# 2. Poll until terminal. Recommended cadence: 5s, backing off to 30s.
while status not in ("completed", "failed"):
    time.sleep(5)
    r = requests.get(
        f"https://api.kunavo.com/v1/videos/{task_id}",
        headers={"Authorization": f"Bearer {API_KEY}"},
        timeout=30,
    ).json()
    status = r["status"]

if status == "failed":
    raise RuntimeError(r["error"]["message"])
print(r["output"]["url"])

OpenAI SDK'sını kullanırken, aşağıda gösterildiği gibi bu gövdeyi client.post ile gönderin ve client.get ile yoklayın. SDK'nın kendi client.videos.create yöntemi burada çalışmaz: yalnızca Sora'nın parametrelerini alır ve bunları çok parçalı form olarak gönderir (Python SDK'sında 2.27.0 sürümünden itibaren); bu uç nokta ise bu çok parçalı isteği 400 hatasıyla reddeder.

import time
from openai import OpenAI

client = OpenAI(api_key=API_KEY, base_url="https://api.kunavo.com/v1")

# The same JSON body, sent with the client's own post().
task = client.post(
    "/videos",
    body={
        "model": "veo-3",
        "prompt": "a cinematic dolly-in on a red origami crane",
        "aspect_ratio": "16:9",
    },
    # object hands back the JSON as parsed. Passing dict instead raises
    # after the task has been created.
    cast_to=object,
    options={"headers": {"Idempotency-Key": "my-task-uuid"}},
)

while task["status"] not in ("completed", "failed"):
    time.sleep(5)
    task = client.get(f"/videos/{task['id']}", cast_to=object)

if task["status"] == "failed":
    raise RuntimeError(task["error"]["message"])
print(task["output"]["url"])

Yanıt biçimi

AlanTürNotlar
idstringvid_- önekiyle başlayan görev kimliği. Üst akıştaki değişikliklerde sabit kalır.
objectstring"video".
statusstringqueued | in_progress | completed | failed.
modelstringGönderdiğiniz model kısa adı.
created_atintGönderimi kabul ettiğimiz Unix saniye zamanı.
completed_atint | nullSon duruma ulaşılan Unix saniye zamanı — beklemedeyken null.
expires_atintUnix saniyesi, gönderimden 30 gün sonrası: görev en az o zamana kadar sorgulanabilir. Sonuç URL'lerinin süresi dolmaz.
progressint0–100. Şu anda terminal duruma ulaşana kadar 0, ulaştığında ise 100 döndürüyoruz.
outputnesne | nullTamamlandığında {url, urls[], duration_seconds, resolution}. duration_seconds, modelden istenen klip uzunluğudur ve Veo'da null olur; resolution, klibin çözünürlük düzeyidir; düzey kaydedilmemişse null olur.
errornesne | nullBaşarısız olduğunda {code, message}.

Üstbilgiler ve kurallar

  • Idempotency-Key (isteğe bağlı, en fazla 128 karakter) — aynı hesapta aynı anahtarla iki kez gönderim yapıldığında yinelenen görev oluşturmak yerine ilk görev döndürülür. Yeniden deneme döngülerinde kullanışlıdır.
  • POST /v1/videos, yeni bir gönderimde 202 Accepted; bir idempotency anahtarı önceki sonucu yeniden oynattığında ise 200 OK döndürür.
  • GET /v1/videos/{id} yalnızca görev sahibinin hesabı kapsamında çalışır: başka bir hesaba ait görevi sorgulamak 404 döndürür — başka bir kişinin hesap kimliğinin varlığını hiçbir zaman doğrulamayız.
  • Önerilen sorgulama aralığı: 5 sn; üstel geri çekilmeyle en fazla 30 sn. Görevler, modele ve çözünürlüğe bağlı olarak genellikle 30 sn – 5 dk içinde tamamlanır.

Hangisi ne zaman kullanılmalı?

Senkron /v1/video/generationsAsenkron /v1/videos
En uygun kullanımTek seferlik betikler, not defterleriÜretim, mobil cihazlar, uzun süren işler
AğBağlantıyı 9 dk'ya kadar açık tutarSaniyeler içinde gönderin; yoklamayı kendi zamanlamanıza göre yapın
Hata kurtarmaYanıtı kaybetmek = görevi kaybetmekKimlik sona ermeden önce istediğiniz zaman yeniden sorgulayın
EşzamanlılıkHer çağrıda bir sunucu çalışanı kullanırGönderir ve hemen serbest bırakır
Yanıt biçimiOpenAI /images/generations biçimiOpenAI /videos biçimi

Yanıt ve depolama

Yanıt, OpenAI'ın standart biçimindedir — data[].url. URL, kalıcı bir files.kunavo.com bağlantısıdır: Kunavo her sonucu kendi CDN'inde arşivlediğinden, ham üst akış URL'lerinin aksine süresi asla dolmaz. Her klip ayrıca /app/assets bölümünde de görünür.

Sonraki adımlar