Cara kerja

Kode error API video AI: artinya dan kapan harus mencoba ulang

Job generasi video lebih sering gagal dibanding panggilan API biasa: model sedang sibuk, menolak prompt, atau timeout. Panduan ini mencantumkan semua error yang bisa Anda terima, mana yang layak dicoba ulang, dan cara mencoba ulang dengan aman.

Dua tempat error bisa muncul

Job video atau gambar bisa gagal di dua momen, dan kode Anda harus menangani keduanya:

  1. Saat Anda mengirim. POST /v1/generations menjawab dengan status error HTTP dan body seperti {"error": {"code": "...", "message": "..."}}. Tidak ada yang dimulai dan tidak ada yang ditagih.
  2. Saat job berjalan. Submit berhasil dengan 202, tetapi job kemudian berakhir dengan status: "failed". error-nya berisi code, message yang bisa Anda tampilkan kepada orang yang meminta, dan retryable.

Job yang gagal tidak pernah ditagih di model mana pun. Harganya ditahan dari saldo Anda saat submit dan dilepas kembali jika job gagal.

Error HTTP saat submit

Kode error HTTP dari endpoint generations
StatusKodeArtiCoba ulang?
400invalid_requestBody bukan JSON, tidak memiliki model atau input, atau berisi field yang tidak dikenal API.Tidak. Perbaiki body.
401unauthorizedKunci API tidak ada atau salah.Tidak. Periksa kuncinya.
402insufficient_creditsSaldo tidak cukup untuk harga yang ditahan bagi job ini.Setelah top-up.
403account_disabled, generation_not_enabledAkun dijeda, atau kunci bisa membaca harga tetapi tidak bisa membuat generasi.Tidak. Hubungi dukungan.
404not_foundTidak ada generasi dengan id tersebut di akun Anda.Tidak.
409idempotency_conflictIdempotency-Key sudah dipakai dengan body yang berbeda.Dengan kunci baru.
409not_readyAnda meminta file sebelum job berhasil.Ya, setelah berhasil.
413body_too_largeBody JSON lebih dari 1 MB. Unggah file dan kirim tautannya.Tidak. Perkecil body.
422invalid_inputNilai yang tidak diterima model, seperti durasi atau ukuran yang tidak ada dalam daftarnya. Pesan error menyebutkan yang mana.Tidak. Ubah nilainya.
422max_cost_exceededSetiap rute lebih mahal daripada max_cost_usd Anda.Tidak. Naikkan batasnya atau turunkan pengaturannya.
422model_not_availableTidak ada model dengan id tersebut.Tidak. Periksa id-nya.
429rate_limitedTerlalu banyak permintaan dalam detik yang sama dari satu akun.Ya, setelah Retry-After.
429concurrency_limitAkun sudah mencapai jumlah maksimum job yang berjalan.Ya, saat salah satu selesai.
500server_errorAda masalah di sisi kami.Ya, dengan Idempotency-Key yang sama.
503busyBeban sesaat.Ya, setelah Retry-After, dengan kunci yang sama.
503model_unavailableSaat ini tidak ada rute yang aktif untuk model ini.Ya, sebentar lagi.

Aturan praktisnya: 429, 500 dan 503 layak dicoba ulang dengan backoff; semua kode di rentang 4xx kecuali 429 berarti permintaannya sendiri harus diubah.

Mengapa job gagal setelah dimulai

Kode error pada generasi yang gagal
error.coderetryableApa yang terjadi
content_policynoModel menolak prompt atau media, atau menahan hasilnya. reason menjelaskan alasannya: sexual, minors, copyright, real_person atau other.
invalid_inputnoReferensi tidak bisa dibaca, atau model menolak sebuah nilai. Pesan error menyebutkan yang mana.
model_declinednoModel menjawab dengan kata-kata, bukan membuat gambar atau video. Deskripsikan hasil yang diinginkan langsung di prompt.
reference_changednoFile referensi berubah setelah diperiksa. Kirim ulang.
max_cost_exceedednoSatu-satunya rute yang bisa menjalankannya lebih mahal daripada batas Anda.
model_busyyesSemua rute sedang penuh. Coba lagi dalam semenit.
model_unavailableyesSaat ini tidak ada rute yang bisa menerima job.
timeoutyesTidak ada rute yang mengembalikan hasil tepat waktu, atau max_wait_s Anda sudah lewat.
all_routes_failedyesSemua rute gagal karena masalah di sisinya.

Di balik layar, job yang menemui rute sibuk atau rusak akan pindah sendiri ke rute berikutnya, jadi saat Anda melihat model_busy atau all_routes_failed, semua rute sudah dicoba. Field attempts menyebutkan jumlahnya. Menunggu satu atau dua menit sebelum mencoba lagi biasanya sudah cukup.

Penolakan konten

content_policy adalah kegagalan yang paling sering dialami. Modellah, bukan API, yang memutuskannya, dan reason memberi tahu aturan mana yang aktif. Penyebab umumnya adalah nama atau wajah orang terkenal di prompt atau gambar referensi (real_person), merek dan karakter terkenal (copyright), serta apa pun yang terbaca melibatkan anak di bawah umur. Mencoba ulang permintaan yang sama tidak akan membantu; ubah kata-kata prompt atau ganti gambarnya. Tingkat ketatnya berbeda antarmodel, jadi prompt yang sama bisa lolos di satu model dan ditolak di model lain.

Loop retry yang melakukan hal yang benar

Helper Python ini mencoba ulang apa yang layak dan berhenti pada apa yang tidak. Dua detail penting:

  • Mengirim ulang submit setelah 503 atau koneksi terputus memakai sama Idempotency-Key yang sama, sehingga tidak akan pernah memulai job kedua yang berbayar.
  • Mencoba lagi setelah job gagal memakai kunci baru. Kunci yang sama hanya akan mengembalikan job yang gagal itu.
Python
import os
import time
import uuid

import requests

API = "https://api.revana.si/v1"
AUTH = {"Authorization": f"Bearer {os.environ['REVANA_API_KEY']}"}
RETRY_HTTP = {429, 500, 503}


class GenerationError(Exception):
    pass


def submit(body):
    """POST a job. Retries 429, 500 and 503 with the same Idempotency-Key, so a retry never starts a second job."""
    headers = {**AUTH, "Idempotency-Key": str(uuid.uuid4())}
    for attempt in range(6):
        r = requests.post(f"{API}/generations", headers=headers, json=body, timeout=60)
        if r.ok:
            return r.json()
        if r.status_code in RETRY_HTTP:
            time.sleep(float(r.headers.get("Retry-After", 2 ** attempt)))
            continue
        err = r.json()["error"]  # 400, 401, 402, 403, 409, 413, 422: fix the request, do not retry
        raise GenerationError(f"{r.status_code} {err['code']}: {err['message']}")
    raise GenerationError("still busy after 6 tries")


def wait(job):
    while job["status"] in ("queued", "running"):
        time.sleep(5)
        job = requests.get(f"{API}/generations/{job['id']}", headers=AUTH).json()
    return job


def generate(body, tries=3):
    for n in range(tries):
        job = wait(submit(body))  # each call uses a new key: a failed job is final
        if job["status"] == "succeeded":
            return job
        err = job["error"]
        if not err["retryable"]:
            raise GenerationError(f"{err['code']}: {err['message']}")
        time.sleep(60 * (n + 1))  # model_busy, timeout and the like: wait, then try again
    raise GenerationError(f"gave up after {tries} tries: {err['code']}")


job = generate({
    "model": "seedance-2.0-fast",
    "input": {"prompt": "Waves roll onto black sand at sunset.", "resolution": "480p", "duration": 5},
    "max_cost_usd": 0.3,
})
print(job["output"]["urls"][0], job["cost_usd"])

Job contoh adalah klip Seedance 2.0 Fast 480p berdurasi 5 detik, yang berharga $0.25 jika berhasil dan gratis jika gagal. Batas max_cost_usd mencegah pengaturan yang salah menghabiskan biaya lebih dari perkiraan.

Menghindari error sejak awal

  • Baca opsinya sebelum mengirim. GET /v1/models dan halaman model mencantumkan ukuran, durasi, dan batas referensi setiap model. Nilai di luar daftar itu langsung ditolak dengan 422 invalid_input.
  • Unggah file, jangan disematkan. POST /v1/uploads menerima gambar hingga 30 MB, klip hingga 50 MB, dan suara hingga 15 MB, lalu mengembalikan tautan yang berlaku 14 hari, sehingga body permintaan tetap kecil.
  • Periksa saldo Anda lewat kode. GET /v1/balance sebelum batch besar menghindarkan Anda dari rentetan error 402. Paket kredit ada di halaman harga.

Untuk cara memangkas biaya job yang berhasil, lihat cara memangkas biaya API video AI. Referensi error lengkap ada di dokumentasi; dapatkan kunci API untuk mencobanya.

Pertanyaan yang sering diajukan

Apakah saya ditagih jika generasi video AI gagal?

Tidak. Harganya ditahan saat Anda mengirim dan dilepas kembali jika job gagal, apa pun penyebabnya.

Error mana yang perlu dicoba ulang?

Saat submit, coba ulang 429, 500 dan 503 setelah jeda Retry-After. Pada job yang gagal, coba ulang jika error.retryable bernilai true: model_busy, model_unavailable, timeout, dan all_routes_failed.

Apa arti content_policy?

Model menolak prompt atau media Anda, atau menahan hasil yang dibuatnya. Kolom reason menyebutkan aturan mana: sexual, minors, copyright, real_person, atau other. Ubah permintaannya, jangan dicoba ulang begitu saja.

Bagaimana mencoba ulang tanpa membayar dua kali?

Kirim header Idempotency-Key dan pakai kembali saat Anda mengirim ulang setelah timeout atau 503. Anda akan mendapat generasi yang sama, bukan generasi kedua.

Apa arti 422 invalid_input?

Model tidak menerima nilai yang Anda kirim, seperti durasi, ukuran, atau jumlah gambar referensi. Pesan error menyebutkan field-nya dan nilai yang diterima.

Bangun di atas API yang tidak pernah menagih kegagalan

Satu kunci API untuk semua model video dan gambar, dengan fallback otomatis antarrute. Kredit prabayar mulai $10, hanya ditagih untuk job yang berhasil.