DokumentasiMenangani error
Menangani error
Pahami respons error dan kegagalan transkripsi, lalu tentukan kapan request perlu diperbaiki atau dicoba ulang.
Bedakan request yang ditolak API dengan transkripsi yang gagal setelah diterima. Pada kasus pertama, Anda mendapat respons error langsung. Pada kasus kedua, job sudah dibuat, tetapi akhirnya memiliki status bernilai failed.
Struktur respons error
Jika request ke /v1 ditolak, respons error mengikuti format berikut:
{
"error": {
"code": "insufficient_minutes",
"message": "Not enough minutes",
"retryable": false,
"action_url": "https://transcript1.com/dashboard/billing",
"minutes_needed": 20,
"minutes_remaining": 3
}
}Gunakan code untuk menentukan penanganan di aplikasi. Teks message boleh ditampilkan kepada pengguna, tetapi jangan jadikan teksnya patokan karena bisa berubah. Nilai retryable: true menandakan request yang sama mungkin berhasil jika dicoba lagi nanti.
Selain retryable, beberapa error menyertakan informasi tambahan:
| Field | Kode error | Keterangan |
|---|---|---|
action_url | insufficient_minutes, no_active_plan, topup_needs_user | Link untuk membeli paket atau top-up. |
minutes_needed, minutes_remaining | insufficient_minutes | Jumlah menit yang dibutuhkan request dan saldo menit Anda. Kebutuhan menit bernilai null jika belum diketahui. |
reason, packs | topup_needs_user | Alasan kartu tidak ditagih, dan jumlah bundel yang diminta. |
supported_platforms | unsupported_platform | Daftar nilai platform yang diterima: ["youtube", "x", "tiktok", "instagram", "facebook", "bluesky", "twitch", "dailymotion", "pinterest", "linkedin", "snapchat"]. |
missing_chunks | upload_incomplete | Daftar indeks chunk yang belum sampai ke server. |
max_bytes | media_too_large | Batas ukuran file yang berlaku untuk Anda, dalam byte. |
params | invalid_request | Rincian validasi body atau query: setiap field dipasangkan dengan penjelasan masalahnya. |
Saat API menolak request
| Status HTTP | code | Bisa retry | Penyebab dan tindakan |
|---|---|---|---|
| 400, 422 | invalid_request | Tidak | Ada parameter atau field body yang belum diisi atau tidak valid. Contohnya diarize bersama source: "captions", atau reuse_recent bersama webhook_url. Body yang bukan JSON valid juga memakai kode ini. |
| 422 | invalid_url | Tidak | Link tidak diterima atau platform tidak sesuai dengan link. Gunakan YouTube, X, TikTok, Instagram, Facebook, Bluesky, atau platform lain dalam daftar sumber. |
| 422 | unsupported_platform | Tidak | Nilai platform tidak termasuk platform yang didukung. |
| 422 | unsupported_media | Tidak | Ekstensi file unggahan tidak didukung. |
| 401 | unauthorized | Tidak | Kredensial belum dikirim, tidak valid, sudah kedaluwarsa, atau sudah dicabut. Kode ini juga berlaku untuk token unggahan yang tidak valid atau kedaluwarsa. |
| 403 | insufficient_scope | Tidak | Token OAuth belum memiliki scope transcriptions:read atau transcriptions:write yang diperlukan. |
| 403 | email_not_verified | Tidak | Alamat email belum diverifikasi. Selesaikan verifikasi sebelum membuat transkripsi atau sesi langsung. |
| 402 | insufficient_minutes | Tidak | Saldo menit yang bisa dipakai sudah 0 atau tidak cukup untuk transkripsi ini, atau kurang dari satu menit yang dimulai pada sesi langsung. Jika top-up otomatis aktif, transcript1 mencoba top-up lebih dulu. Beli menit di action_url, atau biarkan agen membelinya dengan POST /v1/topups atau tool MCP top_up. |
| 402 | no_active_plan | Tidak | Pembelian top-up memerlukan paket berbayar aktif. Kode ini berasal dari POST /v1/topups dan endpoint penagihan dasbor, bukan endpoint transkripsi. |
| 402 | topup_needs_user | Hanya untuk pending dan in_progress | POST /v1/topups tidak menagih kartu. reason menjelaskan alasannya: not_allowed (kredensial tidak boleh membeli top-up, atau pemiliknya bukan admin tim), cap_reached (batas bulanan untuk agen sudah tidak cukup), card_declined, authentication_required, atau no_card. Pengguna bisa membeli bundel di action_url. Untuk pending (pembayaran belum dikonfirmasi) dan in_progress (top-up lain sedang berjalan), tagihan masih mungkin berhasil: coba lagi nanti dengan Idempotency-Key yang sama, bukan meminta pengguna membeli. |
| 404 | not_found | Tidak | Tidak ada transkripsi dengan ID tersebut, atau transkripsi milik tim lain. |
| 409 | upload_incomplete | Tidak | Belum semua chunk diterima. Kirim bagian yang kurang, lalu ulangi langkah penyelesaian unggahan. |
| 409 | invalid_state | Tidak | Transkripsi tidak sedang menunggu unggahan. Anda tidak bisa mengirim chunk atau menyelesaikan unggahan. |
| 409 | session_ended | Tidak | Sesi langsung sudah berakhir, sehingga POST /v1/live/sessions/:id/token tidak bisa menerbitkan token. Juga dikirim sebagai event error WebSocket. |
| 422 | unsupported_language | Tidak | language pada sesi langsung tidak didukung. |
| 422 | unsupported_translation | Tidak | Bahasa translate_to pada sesi langsung tidak didukung, atau terjemahan langsung tidak tersedia. |
| 409 | idempotency_conflict | Tidak | Header Idempotency-Key sudah dipakai untuk parameter yang berbeda. |
| 413 | media_too_large | Tidak | File melewati batas ukuran Anda. Periksa batas unggahan. |
| 413 | invalid_request | Tidak | Body JSON melebihi 1 MB. Untuk file yang terlalu besar, kodenya media_too_large. |
| 429 | rate_limited | Ya | Jumlah request per menit melewati batas. Tunggu sesuai jumlah detik pada Retry-After. |
| 429 | too_many_active_jobs | Ya | Terlalu banyak transkripsi berjalan atau sesi unggahan terbuka. Tunggu sesuai jumlah detik pada Retry-After. |
| 429 | too_many_live_sessions | Ya | Semua sesi langsung bersamaan pada paket Anda sedang terpakai. Tunggu sesuai jumlah detik pada Retry-After (30). |
| 500 | internal_error | Ya | Ada masalah pada sistem kami. Coba kembali beberapa saat lagi. |
| 503 | service_unavailable | Ya | transcript1 sementara tidak bisa diakses. Coba kembali beberapa saat lagi. |
| 503 | live_capacity | Ya | Seluruh kapasitas langsung sedang terpakai. Tunggu sesuai jumlah detik pada Retry-After (30), lalu buat sesi lagi. |
| 503 | live_unavailable | Tidak | Transkripsi langsung sedang tidak tersedia. |
Jika browser memakai cookie login sebagai autentikasi, API juga memeriksa origin request. Akses dari situs lain mendapat 403 forbidden_origin. Pemeriksaan ini tidak berlaku untuk request API yang memakai header Authorization dengan kredensial bearer.
Semua respons 429 menyertakan Retry-After dalam detik. Rincian batasnya ada di biaya dan batas penggunaan.
Tentukan kapan perlu retry
- Retry hanya untuk
retryablebernilaitrue:rate_limited,too_many_active_jobs,too_many_live_sessions,live_capacity,internal_error,service_unavailable, dantopup_needs_userdenganreasonpendingatauin_progress. Jika adaRetry-After, tunggu sesuai nilainya. Jika tidak, tambah jeda pada setiap percobaan. - Saat mengulang
POST /v1/transcriptionsatauPOST /v1/topups, pakai headerIdempotency-Keyyang sama. Dengan begitu, Anda tidak terkena biaya kedua jika request pertama ternyata sudah berhasil. - Untuk kode lain, perbaiki request terlebih dahulu. Mengirim request yang sama tanpa perubahan tidak menyelesaikan masalahnya.
Transkripsi langsung
POST /v1/live/sessions dan endpoint langsung lainnya memakai struktur error yang sama. invalid_request, unsupported_language, insufficient_minutes, dan email_not_verified juga berlaku untuk endpoint tersebut, bersama kode khusus transkripsi langsung pada tabel di atas. Pembuatan sesi tidak idempoten, jadi percobaan ulang setelah too_many_live_sessions atau live_capacity membuat sesi baru.
Setelah sesi ada, masalah datang lewat WebSocket sebagai event error dan kode penutupan, bukan sebagai error HTTP. Lihat Transkripsi langsung untuk semua event.
| Kode penutupan | Arti |
|---|---|
1000 | Penutupan normal, setelah session.ended. |
1011 | Error server yang tidak terduga. Lanjutkan dengan token baru. |
1012 | Server restart, setelah reconnect. Lanjutkan dengan token baru. |
4001 | Token tidak valid, kedaluwarsa, atau sudah dipakai. |
4004 | Sesi tidak ditemukan atau sudah berakhir. |
4008 | Pelanggaran protokol: frame audio berukuran ganjil atau terlalu besar. |
4010 | Digantikan oleh koneksi yang lebih baru ke sesi yang sama. |
Sesi langsung yang berakhir karena alasan seperti balance_exhausted atau idle_timeout bukanlah error: sesi mengirim session.ended dengan alasan berakhir dan disimpan. Lihat Alasan berakhir.
Saat proses transkripsi gagal
Job bisa gagal setelah API menerima request dan mengirim respons. Jika status berubah menjadi failed, objek transkripsi memuat error: { "code", "message" }. Periksa error saat polling atau ketika menerima webhook transcription.failed. Jika terjemahan gagal, webhook transcription.translation.failed dikirim dan transkrip tidak pernah ikut gagal.
error.code | Penyebab | Langkah berikutnya |
|---|---|---|
media_unavailable | Video tidak ditemukan atau sudah tidak tersedia. | Jangan langsung retry. Periksa URL. |
media_private | Video hanya bisa diakses secara privat. | Gunakan postingan publik, atau video YouTube berstatus publik maupun unlisted. |
login_required | Platform meminta Anda login untuk mengakses video. | Tidak ada retry untuk kegagalan permanen ini. |
no_audio | Video tidak memiliki track audio. | Tidak ada retry untuk kegagalan permanen ini. |
age_restricted | Video memiliki batasan usia. | Unggah file rekamannya, bukan mengulang link yang sama. |
live_stream | Siaran masih berlangsung atau belum dimulai. | Coba lagi setelah siaran berakhir. |
no_captions | Mode captions pada source tidak menemukan track subtitle yang bisa dipakai. | Ubah ke source: "auto" atau "stt". |
media_too_long | Durasi melebihi batas speech to text, yaitu 5 jam. | Bagi rekaman menjadi beberapa bagian sebelum mengirimnya lagi. |
unsupported_media | File tidak bisa dibaca atau tidak memiliki track audio. | Kirim file dengan format yang didukung. |
no_speech | Tidak ada ucapan yang terdeteksi. | Jangan retry. |
unsupported_language | Bahasa dalam rekaman tidak didukung. | Ubah language ke kode yang didukung atau "auto" sebelum mencoba lagi. |
insufficient_minutes | Saldo menit habis sebelum transkripsi bisa ditagih, dan top-up otomatis, jika aktif, tidak berhasil menambah menit. | Isi saldo dengan top-up, lalu coba lagi. |
fetch_failed | Media tetap gagal diambil setelah beberapa percobaan. | Boleh dicoba lagi nanti. |
transcription_failed | Speech to text tetap gagal setelah beberapa percobaan. | Boleh dicoba lagi nanti. |
Jika transkripsi gagal atau dibatalkan, Anda tidak membayar. Menit yang sudah dipotong untuk job tersebut dikembalikan ke saldo.
Pembaruan terakhir 5 November 2026