DokumentasiTranskripsi langsung
Transkripsi langsung
Kirim audio mikrofon atau tab ke transcript1 lewat WebSocket dan terima baris subtitle, dengan terjemahan real-time opsional, saat orang masih berbicara.
Transkripsi langsung mengubah aliran audio menjadi baris subtitle saat orang masih berbicara. Klien Anda mengirim audio PCM mentah lewat WebSocket, lalu transcript1 mengirim balik baris yang awalnya berupa dugaan sementara dan kemudian menjadi final. Tambahkan translate_to agar setiap baris juga membawa terjemahannya. Setelah sesi berakhir, hasilnya disimpan sebagai transkripsi biasa.
Tidak ada paket khusus untuk fitur langsung: transkripsi langsung memakai saldo menit yang sama dengan fitur lainnya. Lihat Biaya untuk cara waktu terhubung dihitung.
Kapan memakai transkripsi langsung
| Pakai transkripsi langsung jika | Pakai transkripsi biasa jika |
|---|---|
| Audio masih berlangsung: panggilan, presentasi, siaran, atau video yang sedang Anda tonton. | Anda punya tautan atau file yang sudah jadi. |
| Anda butuh subtitle satu atau dua detik setelah ucapan. | Anda mengutamakan akurasi terbaik dan bisa menunggu hasilnya. |
| Anda ingin terjemahan real-time di samping setiap baris. | Anda ingin menerjemahkan transkrip yang sudah selesai, atau ke beberapa bahasa. |
Transkripsi langsung hanya menerima audio, dalam bentuk PCM mentah. Tautan video, unggahan file, WebM, Opus, dan MP3 tidak diterima. Tangkap audio di klien dan ubah ke PCM terlebih dahulu. Menangkap audio di browser menunjukkan caranya.
Mulai cepat dengan SDK
Pasang SDK 1.5.0 atau yang lebih baru: npm i @transcript1/sdk@latest. t1.live.start membuat sesi, terhubung, lalu selesai setelah sesi dimulai, sehingga Anda bisa langsung mengirim audio.
import { createReadStream } from 'node:fs';
import { setTimeout as sleep } from 'node:timers/promises';
import { Transcript1 } from '@transcript1/sdk';
const t1 = new Transcript1(); // reads TRANSCRIPT1_API_KEY
const live = await t1.live.start({ language: 'en', translateTo: 'es', sampleRate: 16000 });
live.on('line', line => {
const mark = line.final ? 'final ' : 'partial';
console.log(mark, line.text, '→', line.translation?.text ?? '');
});
live.on('warning', warning => console.warn(warning.code));
// speech.pcm: 16 kHz, mono, signed 16-bit little-endian, no header
for await (const chunk of createReadStream('./speech.pcm', { highWaterMark: 3200 })) {
live.send(chunk);
await sleep(100); // 3,200 bytes are 100 ms of audio: send at real-time speed
}
const result = await live.end();
console.log(result.reason, result.transcriptionId, result.minutesCharged);Baris diperbarui di tempat. Ganti baris yang sudah Anda punya ketika baris dengan id yang sama tiba, atau baca semuanya dari live.lines. end() menyelesaikan sesi, menunggu baris terakhir, dan menyimpan transkrip. Lihat SDK Node.js untuk semua metode dan event.
Mulai cepat dengan WebSocket mentah
Tanpa SDK ada dua langkah: buat sesi lewat HTTPS, lalu buka WebSocket dengan token sekali pakai yang dikembalikan.
Membuat sesi
curl -X POST https://api.transcript1.com/v1/live/sessions \
-H "Authorization: Bearer $TRANSCRIPT1_API_KEY" \
-H "Content-Type: application/json" \
-d '{"language": "en", "translate_to": "es", "sample_rate": 16000}'API menjawab 201:
{
"id": "lv_8fK2Lm0PqRsTuVwXyZaBcD",
"status": "waiting",
"transcription_id": "tr_3NcQvXy7BtHjKd5ErFgLmA",
"websocket_url": "wss://api.transcript1.com/v1/live/sessions/lv_8fK2Lm0PqRsTuVwXyZaBcD/stream",
"token": "Zk3x...",
"token_expires_at": "2026-11-02T12:01:00Z",
"rate": 1
}transcription_id bernilai null jika save adalah false. Token hanya berlaku sekali dan kedaluwarsa dalam 60 detik, jadi segera terhubung. rate adalah jumlah menit saldo yang ditagih per menit yang dimulai dalam sesi ini; lihat Biaya.
Body request menerima field berikut. Semuanya opsional, dan scope yang dibutuhkan adalah transcriptions:write:
| Field | Bawaan | Aturan |
|---|---|---|
language | auto | auto, atau kode dua huruf yang didukung transkripsi langsung. |
translate_to | tidak ada | Kode dua huruf. Satu bahasa tujuan per sesi. Lihat Terjemahan langsung. |
diarize | false | Memberi label pembicara. Sebagian konfigurasi tidak bisa memberi label pembicara, misalnya bersama language: "auto", dan menjawab 422. Periksa kemampuan. |
audio_format | pcm_s16le | Satu-satunya nilai. Field ini ada agar format lain bisa ditambahkan nanti. |
sample_rate | 16000 | Bilangan bulat dari 8000 sampai 48000. Hanya mono. |
save | true | false tidak menyimpan apa pun setelah sesi berakhir. Lihat Transkrip tersimpan. |
Terhubung dan streaming
Buka WebSocket dengan token sebagai subprotokol kedua. Cara ini berjalan di browser dan di Node 22+ tanpa header khusus. Tunggu session.started sebelum mengirim audio: frame biner yang dikirim lebih awal dibuang, dan Anda mendapat peringatan audio_dropped.
import { createReadStream } from 'node:fs';
import { setTimeout as sleep } from 'node:timers/promises';
const session = await fetch('https://api.transcript1.com/v1/live/sessions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.TRANSCRIPT1_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ language: 'en', translate_to: 'es', sample_rate: 16000 }),
}).then(response => response.json());
const ws = new WebSocket(session.websocket_url, ['t1-live', session.token]);
const lines = new Map();
ws.addEventListener('message', async message => {
const event = JSON.parse(message.data);
if (event.type === 'session.started') {
for await (const chunk of createReadStream('./speech.pcm', { highWaterMark: 3200 })) {
ws.send(chunk);
await sleep(100);
}
ws.send(JSON.stringify({ type: 'end' }));
} else if (event.type === 'line') {
lines.set(event.line.id, event.line); // the full current state: replace by id
console.log(event.line.final, event.line.text, event.line.translation?.text);
} else if (event.type === 'session.ended') {
console.log('ended:', event.reason, event.minutes_charged);
}
});
ws.addEventListener('close', event => console.log('closed', event.code));Node 20 tidak punya WebSocket bawaan: pakai paket ws, yang memiliki bentuk new WebSocket(url, protocols) yang sama.
Server menjawab token yang valid hanya dengan subprotokol t1-live. Token yang salah tidak pernah menggagalkan handshake: socket terbuka, Anda menerima event error, lalu socket ditutup dengan kode 4xxx, sehingga browser menampilkan alasan sebenarnya, bukan 1006 yang generik. Lihat Kode penutupan.
Menangkap audio di browser
Audio untuk transkripsi langsung harus berupa PCM mono 16-bit bertanda little-endian dengan sample_rate sesi. Browser memberi sampel floating-point, jadi ubah di dalam AudioWorklet. Contoh ini menangkap mikrofon sebagai PCM 16 kHz dalam potongan 100 ms dan mengirimkannya lewat entri SDK untuk browser. getAccessToken mengembalikan access token OAuth; jangan pernah menaruh kunci API di browser. Lihat Keamanan.
import { createLiveClient } from '@transcript1/sdk/live';
const workletSource = `
class Pcm16Processor extends AudioWorkletProcessor {
constructor() {
super();
this.buffer = new Int16Array(1600); // 100 ms at 16 kHz
this.filled = 0;
}
process(inputs) {
const channel = inputs[0][0];
if (!channel) return true;
for (let i = 0; i < channel.length; i++) {
const sample = Math.max(-1, Math.min(1, channel[i]));
this.buffer[this.filled++] = sample < 0 ? sample * 0x8000 : sample * 0x7fff;
if (this.filled === this.buffer.length) {
this.port.postMessage(this.buffer.slice());
this.filled = 0;
}
}
return true;
}
}
registerProcessor('pcm16', Pcm16Processor);
`;
const client = createLiveClient({ getAccessToken: () => myApp.getOAuthAccessToken() });
const stream = await navigator.mediaDevices.getUserMedia({ audio: { channelCount: 1 } });
const context = new AudioContext({ sampleRate: 16000 });
const moduleUrl = URL.createObjectURL(new Blob([workletSource], { type: 'text/javascript' }));
await context.audioWorklet.addModule(moduleUrl);
// the context's real rate: a browser that cannot do 16 kHz picks its own
const live = await client.start({ language: 'auto', sampleRate: context.sampleRate });
live.on('line', renderLine);
const microphone = context.createMediaStreamSource(stream);
const capture = new AudioWorkletNode(context, 'pcm16');
capture.port.onmessage = event => live.send(event.data); // an Int16Array
const mute = context.createGain();
mute.gain.value = 0;
microphone.connect(capture).connect(mute).connect(context.destination);
async function stop() {
stream.getTracks().forEach(track => track.stop());
await context.close();
return live.end();
}Worklet ini ditulis untuk 16 kHz. Jika konteks berjalan pada laju lain, potongan tidak lagi 100 ms, tetapi PCM tetap benar karena sampleRate sama dengan konteks. Untuk menangkap suara tab atau video, bukan mikrofon, buat MediaStream dengan getDisplayMedia atau dari captureStream() elemen media, lalu sambungkan dengan cara yang sama.
Terjemahan langsung
Tambahkan translate_to ke sesi, dan transcript1 menerjemahkan setiap baris saat diucapkan.
- Satu bahasa tujuan per sesi. Tambahkan bahasa lain ke transkrip tersimpan setelahnya dengan endpoint terjemahan.
- Setiap
linepunya teks asli (text,final) dan objektranslation(language,text,final).translationbernilainulljikatranslate_totidak diatur. - Teks asli dan terjemahan menjadi final secara terpisah: satu baris bisa punya teks asli yang final sementara terjemahannya masih berubah. Tampilkan baris sebagai final setelah keduanya final.
- Baris yang sudah berbahasa tujuan memakai teksnya sendiri sebagai terjemahan, dan menjadi final saat baris ditutup.
- Baris ditutup saat pembicara berhenti sejenak, pembicara berganti, jeda antarkata lebih dari 0.9 detik, baris mencapai dua baris subtitle (84 karakter) atau 15 detik, atau Anda mengirim
finalize. Saat terjemahan aktif, penutupan baris bisa memakan sekitar 3 detik lebih lama sampai terjemahannya tiba. Dalam hal itu terjemahan bisa tetap terbuka (final: false) dan terus bertambah setelah teks asli final. - Terjemahan gratis. Tidak memakai menit.
Bahasa tujuan dan pasangan bahasa yang tersedia bergantung pada penyedia ucapan langsung. Baca kemampuan alih-alih menuliskan aturan secara permanen di kode. Tujuan yang tidak didukung menghasilkan 422 unsupported_translation. Misalnya, penyedia bisa mewajibkan language yang eksplisit alih-alih auto, atau hanya mengizinkan pasangan yang menyertakan bahasa Inggris.
Protokol WebSocket
Terhubung
new WebSocket(websocket_url, ['t1-live', token]);Token dikirim sebagai subprotokol WebSocket. Token tidak pernah muncul di URL atau log akses. Jangan kirim header Authorization: token itulah kredensialnya. Server mengirim ping setiap 30 detik; browser dan paket ws menjawab otomatis. Socket yang tidak mengirim pong selama 60 detik diputus.
Koneksi valid ke sesi yang sudah punya socket akan menggantikan socket lama. Lihat Melanjutkan dan mengambil alih.
Pesan dari klien
| Pesan | Arti |
|---|---|
| Frame biner | Audio: PCM s16le mono dengan sample_rate sesi. Setiap frame berukuran genap dan paling besar 256 KB. Sekitar 100 ms per frame adalah ukuran yang baik. |
{"type":"finalize"} | Menutup baris saat ini sekarang juga, misalnya saat video dijeda. |
{"type":"end"} | Mengakhiri sesi dan menyimpannya. Server menjawab session.ended lalu menutup socket. |
| Selain itu | Event error yang tidak fatal dengan kode invalid_message. |
Frame berukuran ganjil atau terlalu besar adalah pelanggaran protokol dan menutup socket dengan 4008.
Mulai kirim audio setelah session.started. Klien yang mengirim audio lebih cepat dari waktu nyata ditagih berdasarkan durasi audio, bukan waktu terhubung (lihat Biaya), jadi kirim audio sesuai kecepatan audio itu dihasilkan.
Event dari server
Setiap event adalah frame teks JSON dengan type.
| Event | Dikirim saat |
|---|---|
session.started | Koneksi diterima. Kirim audio mulai sekarang. |
line | Baris subtitle dibuat atau berubah. |
usage | Setelah setiap penagihan. |
warning | Ada hal yang perlu diperhatikan, tetapi sesi berlanjut. |
error | Masalah yang tidak fatal, atau alasan penutupan seketika. |
reconnect | Server akan segera restart. Lanjutkan sesi. |
session.ended | Sesi selesai dan tersimpan. Event terakhir sebelum penutupan normal. |
session.started menyatakan apakah ini kelanjutan sesi dan berapa banyak audio yang sudah diproses sesi:
{
"type": "session.started",
"session_id": "lv_8fK2Lm0PqRsTuVwXyZaBcD",
"transcription_id": "tr_3NcQvXy7BtHjKd5ErFgLmA",
"resumed": false,
"offset_ms": 0
}line membawa keadaan lengkap terkini dari satu baris, jadi ganti baris yang Anda punya dengan id yang sama. Lihat Objek baris.
{
"type": "line",
"line": {
"id": 12,
"start_ms": 53120,
"end_ms": 56040,
"speaker": null,
"language": "en",
"text": "Welcome back to the stream",
"final": true,
"translation": { "language": "es", "text": "Bienvenidos de nuevo", "final": false }
}
}usage dikirim setelah setiap penagihan, berisi waktu terhubung, durasi audio, menit saldo yang sudah ditagih, dan menit yang tersisa:
{
"type": "usage",
"connected_ms": 61240,
"audio_ms": 60100,
"minutes_charged": 2,
"minutes_remaining": 898
}warning memiliki code:
code | Arti |
|---|---|
balance_low | Penagihan berikutnya akan gagal. Sesi berakhir dengan balance_exhausted saat waktunya tiba. Tidak dikirim saat top-up otomatis aktif. |
audio_dropped | Audio tiba sebelum sesi siap, atau terlalu banyak audio tiba saat penyedia ucapan sedang terhubung. Audio terlama dibuang. |
idle_timeout_soon | Tidak ada audio selama 4 menit. Sesi berakhir setelah 5 menit tanpa audio. Kirim audio agar sesi tetap berjalan. |
{ "type": "warning", "code": "idle_timeout_soon" }error memiliki code dan message. Kode berikut bisa tiba di socket langsung:
code | Fatal | Arti |
|---|---|---|
invalid_message | Tidak | Frame teks yang bukan finalize atau end. |
invalid_token | Ya | Token tidak valid, kedaluwarsa, atau sudah dipakai. Socket ditutup dengan 4001. |
not_found | Ya | Sesi tidak ada. Socket ditutup dengan 4004. |
session_ended | Ya | Sesi sudah berakhir. Socket ditutup dengan 4004. |
{ "type": "error", "code": "invalid_message", "message": "Expected {\"type\":\"finalize\"} or {\"type\":\"end\"}" }reconnect datang sebelum server menutup socket dengan 1012, misalnya saat deploy. Ambil token baru dan lanjutkan sesi.
{ "type": "reconnect", "reason": "server_restart" }session.ended adalah event terakhir setiap sesi. Angkanya adalah total akhir:
{
"type": "session.ended",
"reason": "client_ended",
"transcription_id": "tr_3NcQvXy7BtHjKd5ErFgLmA",
"minutes_charged": 3,
"connected_ms": 142500,
"audio_ms": 141900
}Objek baris
| Field | Arti |
|---|---|
id | Nomor berbasis 0 yang bertambah satu untuk setiap baris. Ini adalah indeks segmen di transkrip tersimpan. |
start_ms, end_ms | Awal dan akhir dalam waktu audio sesi. Waktu ini berlanjut melewati sambungan ulang. |
speaker | Label pembicara jika diarize aktif, selain itu null. Labelnya sama dengan transkrip biasa. |
language | Bahasa baris yang terdeteksi atau ditentukan, atau null jika belum diketahui. |
text | Teks asli sejauh ini. |
final | true setelah teks asli tidak akan berubah lagi. |
translation | null tanpa translate_to, selain itu language, text, dan final. |
Tampilkan baris dengan final: false dengan gaya yang lebih pudar: teksnya masih bisa berubah. Teks baris dengan final: true tidak pernah berubah lagi, dan baris final tidak pernah dihapus.
SDK memakai camelCase untuk field baris: startMs, endMs.
Alasan berakhir
session.ended dan GET /v1/live/sessions/:id memberikan end_reason:
| Alasan | Arti |
|---|---|
client_ended | Anda mengirim end. |
balance_exhausted | Penagihan berikutnya gagal. Sesi berakhir pada batas menit dan disimpan. |
idle_timeout | Tidak ada audio selama 5 menit. |
max_duration | Sesi terhubung selama 300 menit. Mulai sesi baru. |
disconnected | Klien menghilang lebih dari 2 menit tanpa melanjutkan sesi. |
upstream_error | Penyedia ucapan gagal. |
internal_error | Terjadi masalah di sisi kami. |
not_connected | Sesi tidak pernah terhubung dalam 5 menit. Sesi ini tidak pernah ditagih dan hanya terlihat lewat GET. |
Kode penutupan
| Kode | Arti |
|---|---|
1000 | Penutupan normal. Selalu mengikuti session.ended. |
1011 | Error server yang tidak terduga. Sesi dipulihkan oleh server: lanjutkan dengan token baru. |
1012 | Server restart. Mengikuti reconnect: lanjutkan dengan token baru. |
4001 | Token tidak valid, kedaluwarsa, atau sudah dipakai. |
4004 | Sesi tidak ditemukan atau sudah berakhir. |
4008 | Pelanggaran protokol: frame biner berukuran ganjil atau terlalu besar. |
4010 | Digantikan oleh koneksi yang lebih baru ke sesi yang sama. |
Selama API restart, request WebSocket baru bisa dijawab dengan HTTP 503. Coba lagi sebentar lagi.
Melanjutkan dan mengambil alih
Sesi bertahan saat jaringan terputus, saat API di-deploy, dan saat terjadi crash. Selama 2 menit setelah terputus, sesi menunggu Anda; setelah itu sesi berakhir sebagai disconnected dan disimpan.
- Panggil
POST /v1/live/sessions/:id/token. Responsnya berisitoken,token_expires_at, danwebsocket_url, field yang sama seperti saat Anda membuat sesi. Panggilan ini gagal dengan409 session_endedsetelah sesi berakhir. - Buka WebSocket baru dengan token itu.
session.startedtiba denganresumed: true.offset_msadalah jumlah audio yang sudah diproses sesi: lanjutkan audio dari titik itu. Id baris berlanjut.
Baris yang sudah final tetap disimpan. Ekor yang sedang berjalan saat koneksi terputus hilang, jadi jika Anda menyimpan buffer audio, kirim ulang beberapa detik audio mulai dari offset_ms. Jeda saat menyambung ulang tidak ditagih.
Pengambilalihan menggunakan panggilan yang sama. Jika server masih menganggap sebuah socket terbuka, koneksi valid yang baru menggantikannya, dan socket lama ditutup dengan 4010 setelah barisnya disimpan. Melanjutkan sesi tidak pernah terhalang oleh batas sesi bersamaan.
SDK melakukan semua ini untuk Anda: saat koneksi terputus atau event reconnect tiba, SDK mengambil token dan menyambung ulang dengan jeda bertahap 0.5 sampai 8 detik hingga 2 menit, lalu mengirim ulang 10 detik terakhir audio yang Anda kirim selama jeda.
Biaya
Transkripsi langsung memakai saldo menit yang sama dengan transkripsi batch.
- Waktu terhubung yang ditagih, sejak socket diterima sampai ditutup. Keheningan dan video yang dijeda ikut dihitung. Waktu antara koneksi terputus dan dilanjutkan tidak dihitung.
- Per menit yang dimulai, minimum 1. Menit pertama ditagih saat koneksi pertama diterima, dan setiap menit berikutnya saat menit itu dimulai.
- Lebih cepat dari waktu nyata ditagih sebagai durasi audio. Jika audio yang Anda kirim lebih panjang daripada waktu terhubung, durasi audio yang ditagih.
- Tarif dibaca dari API. Satu menit yang dimulai bernilai
ratemenit saldo, dibulatkan ke atas. Tarif biasanya 1 dan bisa berupa desimal. Baca tarif langsung darirates.livediGET /v1/account, dariratediGET /v1/live/capabilities, dan dariratepada sesi yang Anda buat. Tarif sebuah sesi tetap setelah sesi dibuat. - Terjemahan gratis.
- Tidak pernah terhubung berarti tidak ditagih. Sesi yang tidak terhubung dalam 5 menit berakhir sebagai
not_connected. - Kegagalan dikembalikan. Jika sesi berakhir dengan
upstream_erroratauinternal_errorsebelum menghasilkan satu baris pun, semua tagihan dikembalikan. Sesi kosong akibat keheningan tetap ditagih dan disimpan kosong. - Saat saldo habis dan top-up otomatis aktif, transcript1 menagih kartu tersimpan Anda selagi sesi tetap streaming, dan sesi berlanjut. Jika top-up otomatis mati atau dijeda, atau penagihan gagal, sesi diselesaikan, disimpan, dan berakhir dengan
balance_exhaustedpada batas menit. Peringatanbalance_lowdatang lebih dulu, kecuali top-up otomatis aktif.
Membuat sesi menghasilkan 402 insufficient_minutes jika saldo yang bisa dipakai kurang dari satu menit yang dimulai pada tarif saat ini. Jika top-up otomatis aktif, transcript1 mencoba top-up lebih dulu. Lihat Biaya dan batas penggunaan.
Batas
| Free | Monthly | Annual | |
|---|---|---|---|
| Sesi langsung bersamaan | 1 | 2 | 3 |
- Sesi dihitung selama berstatus
waiting,connected, ataudisconnected(dalam jendela 2 menitnya). Jika melewati batas,POST /v1/live/sessionsmenghasilkan429 too_many_live_sessionsdenganRetry-After: 30. - Sesi langsung tidak dihitung dalam batas transkripsi aktif Anda.
- Satu sesi berlangsung paling lama 300 menit waktu terhubung. Setelah itu sesi berakhir dengan
max_duration. - Sesi tanpa audio selama 5 menit berakhir dengan
idle_timeout; Anda mendapatidle_timeout_soonsetelah 4 menit. Aliran yang dijeda tetap menagih waktu terhubung dan dihitung sebagai menganggur, jadi akhiri sesi jika jedanya lama. - transcript1 membatasi semua sesi langsung secara bersama-sama. Jika semuanya terpakai,
POST /v1/live/sessionsmenghasilkan503 live_capacity, yang bisa dicoba ulang. TungguRetry-After(30 detik) lalu coba lagi. Batas ini diperiksa hanya saat sesi dibuat, tidak pernah di tengah sesi. - Membuat sesi dan mengambil token dihitung dalam batas request per menit Anda.
- Audio hanya berupa PCM mentah:
pcm_s16le, mono, 8000 sampai 48000 Hz.
Kemampuan
GET /v1/live/capabilities menjelaskan apa yang saat ini didukung transkripsi langsung, sehingga klien tidak perlu menuliskan aturan penyedia di kode. Scope yang dibutuhkan adalah transcriptions:read.
{
"available": true,
"auto_language": true,
"languages": ["en", "es"],
"translation": {
"targets": ["es", "de"],
"pairs": "any",
"requires_language": false
},
"diarize": true,
"audio_formats": ["pcm_s16le"],
"sample_rate": { "min": 8000, "max": 48000 },
"max_session_minutes": 300,
"rate": 1
}Daftar di atas dipersingkat. Baca daftar lengkapnya dari API.
translation.pairsbernilai"any"(bahasa terdeteksi apa pun ke tujuan apa pun), atau daftar objek denganfromdanto.translation.requires_languagebernilaitruejika terjemahan memerlukanlanguageyang eksplisit alih-alihauto.- Jika transkripsi langsung belum dikonfigurasi, responsnya
available: falsedengan hanyarate, dan pembuatan sesi menghasilkan503 live_unavailable.
Dengan SDK: await t1.live.capabilities().
Membaca sesi
GET /v1/live/sessions/:id mengembalikan keadaan sebuah sesi. Scope yang dibutuhkan adalah transcriptions:read.
curl https://api.transcript1.com/v1/live/sessions/lv_8fK2Lm0PqRsTuVwXyZaBcD \
-H "Authorization: Bearer $TRANSCRIPT1_API_KEY"{
"id": "lv_8fK2Lm0PqRsTuVwXyZaBcD",
"status": "ended",
"end_reason": "client_ended",
"transcription_id": "tr_3NcQvXy7BtHjKd5ErFgLmA",
"options": {
"language": "en",
"translate_to": "es",
"diarize": false,
"audio_format": "pcm_s16le",
"sample_rate": 16000,
"save": true
},
"connected_ms": 142500,
"audio_ms": 141900,
"minutes_charged": 3,
"rate": 1,
"created_at": "2026-11-02T11:58:12Z",
"ended_at": "2026-11-02T12:00:35Z"
}status bernilai waiting, connected, disconnected, atau ended. end_reason bernilai null sampai sesi berakhir. Dengan SDK: await t1.live.get(id).
Error
Error request memakai struktur error yang biasa. Berikut error yang dikembalikan POST /v1/live/sessions dan endpoint pendampingnya:
| Status HTTP | code | Bisa dicoba ulang | Kapan |
|---|---|---|---|
| 422 | invalid_request | Tidak | Ada field yang hilang atau tidak valid, misalnya sample_rate di luar 8000 sampai 48000. |
| 422 | unsupported_language | Tidak | language tidak didukung untuk transkripsi langsung. |
| 422 | unsupported_translation | Tidak | Bahasa tujuan, atau pasangan bahasanya, tidak didukung. |
| 402 | insufficient_minutes | Tidak | Saldo yang bisa dipakai kurang dari satu menit yang dimulai pada tarif saat ini. |
| 403 | email_not_verified | Tidak | Verifikasi alamat email Anda terlebih dahulu. |
| 429 | too_many_live_sessions | Ya | Semua sesi langsung bersamaan pada paket Anda sedang terpakai. Tunggu sesuai Retry-After. |
| 503 | live_capacity | Ya | Seluruh kapasitas langsung sedang terpakai. Tunggu sesuai Retry-After (30 detik). |
| 503 | live_unavailable | Tidak | Transkripsi langsung sedang tidak tersedia. |
| 409 | session_ended | Tidak | POST /v1/live/sessions/:id/token untuk sesi yang sudah berakhir. |
Masalah di socket datang sebagai event error dan kode penutupan.
Transkrip tersimpan
Dengan save: true (bawaan), sesi disimpan sebagai transkripsi biasa saat berakhir. Audio tidak pernah disimpan.
transcription_iddikembalikan saat Anda membuat sesi. Statusnyaliveselama sesi berjalan dancompletedsetelah berakhir. Sesi yang tidak pernah terhubung meninggalkan transkripsi berstatuscanceled.- Transkripsi memiliki
source: { "platform": "live", "session_id": "lv_…" }. Tidak ada tautan atau file. Dasbor menampilkannya sebagai sesi langsung. - Setiap baris menjadi satu segmen, dengan indeks yang sama dengan
idbaris. Baca transkrip sebagai JSON, teks, SRT, atau VTT seperti transkripsi lain: lihat referensi API. - Terjemahan langsung ikut tersimpan. Bacalah dengan parameter
translation, seperti dijelaskan di Terjemahan. - Tambahkan bahasa terjemahan lain nanti dengan
POST /v1/transcriptions/:id/translationssetelah transkripsi berstatuscompleted. Lihat Terjemahan.
Dengan save: false, tidak ada yang disimpan setelah sesi berakhir: tidak ada transkripsi dan transcription_id bernilai null. Anda tetap menerima setiap baris lewat socket dan tagihan biasa tetap berlaku.
Keamanan
- Token yang Anda terima saat membuat sesi hanya berlaku sekali dan kedaluwarsa dalam 60 detik. Token dikirim sebagai subprotokol WebSocket, bukan di URL, sehingga tidak masuk log akses. Token yang bocor tidak berguna setelah dipakai atau kedaluwarsa.
- Gunakan kunci API hanya dari server yang Anda kendalikan. Jangan pernah menaruh kunci API di halaman web atau ekstensi.
- Di browser atau ekstensi, masukkan pengguna dengan OAuth dan teruskan access token OAuth ke
getAccessTokenpadacreateLiveClient. Token memerlukan scopetranscriptions:writeuntuk memulai sesi. Access token OAuth kedaluwarsa setelah 1 jam, dan setiap kelanjutan sesi meminta token baru darigetAccessToken. - Server Anda juga bisa membuat sesi dengan kunci API lalu hanya memberikan
websocket_urldantokenke browser. Klien kemudian terhubung langsung. Klien tidak bisa melanjutkan sesi tanpa token baru dari Anda.
Pembaruan terakhir 3 November 2026