DocumentatieLive transcriptie
Live transcriptie
Stream microfoon- of tabaudio via een WebSocket naar transcript1 en krijg ondertitelregels terug terwijl mensen praten, met optioneel realtime vertaling.
Live transcriptie zet een audiostream om in ondertitelregels terwijl mensen nog praten. Je client stuurt ruwe PCM-audio over een WebSocket, en transcript1 stuurt regels terug die eerst een voorlopige schatting zijn en daarna definitief worden. Voeg translate_to toe en elke regel bevat ook zijn vertaling. Als de sessie eindigt, wordt het resultaat opgeslagen als een gewone transcriptie.
Er zijn geen aparte live-abonnementen: live transcriptie gebruikt hetzelfde minutensaldo als al het andere. Zie Facturatie voor hoe verbonden tijd wordt geteld.
Wanneer gebruik je live
| Gebruik live als | Gebruik een gewone transcriptie als |
|---|---|
| De audio nog wordt gemaakt: een gesprek, een lezing, een stream, een video die je nu bekijkt. | Je een link of een afgerond bestand hebt. |
| Je binnen een of twee seconden na het gesproken woord ondertitels nodig hebt. | Je de beste nauwkeurigheid wilt en op het resultaat kunt wachten. |
| Je realtime vertaling naast elke regel wilt. | Je een vertaling van een afgerond transcript wilt, of meerdere talen. |
Live accepteert alleen audio, als ruwe PCM. Videolinks, uploads, WebM, Opus en MP3 worden niet geaccepteerd. Neem de audio op in je client en zet hem eerst om naar PCM. Audio opnemen in een browser laat zien hoe.
Snel starten met de SDK
Installeer SDK 1.5.0 of nieuwer: npm i @transcript1/sdk@latest. t1.live.start maakt de sessie aan, verbindt en wordt afgerond zodra de sessie is gestart, zodat je meteen audio kunt sturen.
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);Regels worden ter plekke bijgewerkt. Vervang een regel die je al hebt zodra er een met dezelfde id binnenkomt, of lees ze allemaal uit live.lines. end() rondt de sessie af, wacht op de laatste regels en slaat het transcript op. In de Node.js SDK staan alle methoden en events.
Snel starten met een ruwe WebSocket
Zonder SDK zijn er twee stappen: maak een sessie aan via HTTPS en open daarna de WebSocket met het eenmalige token dat je terugkreeg.
Een sessie aanmaken
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}'De API antwoordt met 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 is null als save op false staat. Het token is eenmalig en verloopt na 60 seconden, dus verbind meteen. rate is het aantal saldominuten dat per gestarte minuut van deze sessie wordt afgeschreven; zie Facturatie.
De request body accepteert deze velden. Ze zijn allemaal optioneel en de scope is transcriptions:write:
| Veld | Standaard | Regel |
|---|---|---|
language | auto | auto, of een taalcode van twee letters die live transcriptie ondersteunt. |
translate_to | geen | Een taalcode van twee letters. Eén doeltaal per sessie. Zie Live vertalen. |
diarize | false | Labelt sprekers. Sommige combinaties kunnen geen sprekers labelen, bijvoorbeeld samen met language: "auto", en geven 422. Controleer de mogelijkheden. |
audio_format | pcm_s16le | De enige waarde. Het veld bestaat zodat er later formaten bij kunnen komen. |
sample_rate | 16000 | Een geheel getal van 8000 tot 48000. Alleen mono. |
save | true | false bewaart niets nadat de sessie is afgelopen. Zie Opgeslagen transcripten. |
Verbinden en streamen
Open de WebSocket met het token als tweede subprotocol. Dit werkt in browsers en in Node 22+ zonder eigen headers. Wacht op session.started voordat je audio stuurt: binaire frames die eerder worden verstuurd, worden genegeerd en je krijgt een audio_dropped-waarschuwing.
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));Op Node 20 is er geen ingebouwde WebSocket: gebruik het pakket ws, dat dezelfde vorm new WebSocket(url, protocols) heeft.
De server antwoordt op een geldig token met het subprotocol t1-live en niets anders. Een ongeldig token laat de handshake nooit mislukken: de socket gaat open, je krijgt een error-event en de socket sluit met een 4xxx-code, zodat een browser de echte reden laat zien in plaats van een algemene 1006. Zie Sluitcodes.
Audio opnemen in een browser
Live audio moet 16-bit signed little-endian mono PCM zijn, met de sample_rate van de sessie. Browsers leveren samples als drijvende-kommagetallen, dus converteer ze in een AudioWorklet. Dit fragment neemt de microfoon op als 16 kHz PCM in brokken van 100 ms en verstuurt die via het browser-instappunt van de SDK. getAccessToken geeft een OAuth-toegangstoken terug; zet nooit een API-sleutel in een browser. Zie Beveiliging.
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();
}De worklet is geschreven voor 16 kHz. Draait de context op een andere samplefrequentie, dan is een brok niet langer 100 ms, maar de PCM blijft correct omdat sampleRate overeenkomt met de context. Om het geluid van een tab of een video op te nemen in plaats van de microfoon, maak je de MediaStream met getDisplayMedia of met captureStream() van een media-element en verbind je hem op dezelfde manier.
Live vertalen
Voeg translate_to toe aan de sessie en transcript1 vertaalt elke regel terwijl hij wordt gesproken.
- Eén doeltaal per sessie. Voeg achteraf meer talen toe aan het opgeslagen transcript met het vertaal-endpoint.
- Elke
lineheeft een origineel (text,final) en eentranslation-object (language,text,final).translationisnullalstranslate_toniet is ingesteld. - Het origineel en de vertaling worden onafhankelijk van elkaar definitief: een regel kan een definitief origineel hebben terwijl de vertaling nog verandert. Toon een regel pas als definitief als beide dat zijn.
- Een regel die al in de doeltaal is, gebruikt zijn eigen tekst als vertaling en is definitief zodra de regel sluit.
- Een regel sluit als de spreker pauzeert, de spreker wisselt, een pauze tussen woorden langer is dan 0,9 seconden, de regel twee ondertitelrijen (84 tekens) of 15 seconden bereikt, of je
finalizestuurt. Met vertaling aan kan het ongeveer 3 seconden langer duren voordat een regel sluit, omdat de vertaling nog binnenkomt. In dat geval kan de vertaling open blijven (final: false) en blijven groeien nadat het origineel definitief is. - Vertalen is gratis. Het kost geen minuten.
Welke doeltalen en taalparen beschikbaar zijn, hangt af van de live spraakprovider. Lees de mogelijkheden in plaats van regels hard te coderen. Een niet-ondersteunde doeltaal geeft 422 unsupported_translation. Een provider kan bijvoorbeeld een expliciete language eisen in plaats van auto, of alleen paren toestaan waar Engels in zit.
WebSocket-protocol
Verbinden
new WebSocket(websocket_url, ['t1-live', token]);Het token reist mee als WebSocket-subprotocol. Het komt nooit in een URL of een toegangslog terecht. Stuur geen Authorization-header: het token is het inlogbewijs. De server pingt elke 30 seconden; browsers en het pakket ws antwoorden automatisch. Een socket die 60 seconden geen pong stuurt, wordt verbroken.
Een geldige verbinding met een sessie die al een socket heeft, vervangt de oude. Zie Hervatten en overnemen.
Berichten van de client
| Bericht | Betekenis |
|---|---|
| Binair frame | Audio: PCM s16le mono met de sample_rate van de sessie. Elk frame heeft een even lengte en is maximaal 256 KB. Ongeveer 100 ms per frame is een goede grootte. |
{"type":"finalize"} | Sluit de huidige regel nu, bijvoorbeeld als de video is gepauzeerd. |
{"type":"end"} | Rond de sessie af en sla hem op. De server antwoordt met session.ended en sluit de socket. |
| Al het andere | Een niet-fatale error met de code invalid_message. |
Een frame met een oneven lengte of dat te groot is, is een protocolschending en sluit de socket met 4008.
Begin met audio sturen na session.started. Een client die sneller dan realtime audio stuurt, betaalt voor de audiotijd in plaats van de verbonden tijd (zie Facturatie), dus stuur in het tempo waarin de audio wordt gemaakt.
Server-events
Elk event is een JSON-tekstframe met een type.
| Event | Verstuurd wanneer |
|---|---|
session.started | De verbinding is geaccepteerd. Stuur vanaf nu audio. |
line | Een ondertitelregel is aangemaakt of gewijzigd. |
usage | Na elke afschrijving. |
warning | Er is iets dat aandacht nodig heeft, maar de sessie gaat door. |
error | Een niet-fataal probleem, of de reden voor een directe sluiting. |
reconnect | De server gaat zo herstarten. Hervat de sessie. |
session.ended | De sessie is afgelopen en opgeslagen. Het laatste event vóór een normale sluiting. |
session.started laat weten of dit een hervatting is en hoeveel audio de sessie al heeft verwerkt:
{
"type": "session.started",
"session_id": "lv_8fK2Lm0PqRsTuVwXyZaBcD",
"transcription_id": "tr_3NcQvXy7BtHjKd5ErFgLmA",
"resumed": false,
"offset_ms": 0
}line bevat de volledige huidige staat van één regel, dus vervang de regel die je hebt met dezelfde id. Zie Het line-object.
{
"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 wordt na elke afschrijving verstuurd, met de verbonden tijd, de audiotijd, het aantal saldominuten dat tot nu toe is afgeschreven en de minuten die je nog hebt:
{
"type": "usage",
"connected_ms": 61240,
"audio_ms": 60100,
"minutes_charged": 2,
"minutes_remaining": 898
}warning heeft een code:
code | Betekenis |
|---|---|
balance_low | De volgende afschrijving zou mislukken. De sessie eindigt met balance_exhausted zodra die aan de beurt is. Wordt niet verstuurd als automatisch opwaarderen aanstaat. |
audio_dropped | Er kwam audio binnen voordat de sessie klaar was, of er kwam te veel audio binnen terwijl de spraakprovider verbond. De oudste audio is weggegooid. |
idle_timeout_soon | 4 minuten geen audio. De sessie eindigt na 5 minuten zonder audio. Stuur audio om hem aan te houden. |
{ "type": "warning", "code": "idle_timeout_soon" }error heeft een code en een message. Deze codes kunnen op een live socket voorkomen:
code | Fataal | Betekenis |
|---|---|---|
invalid_message | Nee | Een tekstframe dat niet finalize of end is. |
invalid_token | Ja | Het token is ongeldig, verlopen of al gebruikt. De socket sluit met 4001. |
not_found | Ja | De sessie bestaat niet. De socket sluit met 4004. |
session_ended | Ja | De sessie is al afgelopen. De socket sluit met 4004. |
{ "type": "error", "code": "invalid_message", "message": "Expected {\"type\":\"finalize\"} or {\"type\":\"end\"}" }reconnect komt voordat de server de socket sluit met 1012, bijvoorbeeld tijdens een deploy. Haal een nieuw token op en hervat.
{ "type": "reconnect", "reason": "server_restart" }session.ended is het laatste event van elke sessie. De getallen zijn de eindtotalen:
{
"type": "session.ended",
"reason": "client_ended",
"transcription_id": "tr_3NcQvXy7BtHjKd5ErFgLmA",
"minutes_charged": 3,
"connected_ms": 142500,
"audio_ms": 141900
}Het line-object
| Veld | Betekenis |
|---|---|
id | Een 0-gebaseerd nummer dat bij elke regel met één oploopt. Het is de segmentindex in het opgeslagen transcript. |
start_ms, end_ms | Begin en einde in de audiotijd van de sessie. Deze tijd loopt door na heraansluitingen. |
speaker | Het sprekerlabel als diarize aan staat, anders null. De labels zijn dezelfde als in gewone transcripten. |
language | De gedetecteerde of opgegeven taal van de regel, of null als die nog niet bekend is. |
text | De originele tekst tot nu toe. |
final | true zodra de originele tekst niet meer verandert. |
translation | null zonder translate_to, anders language, text en final. |
Toon regels met final: false in een lichtere stijl: hun tekst kan nog veranderen. De tekst van een regel met final: true verandert nooit meer en een definitieve regel wordt nooit verwijderd.
De SDK gebruikt camelCase voor regelvelden: startMs, endMs.
Eindredenen
session.ended en GET /v1/live/sessions/:id geven een end_reason:
| Reden | Betekenis |
|---|---|
client_ended | Je stuurde end. |
balance_exhausted | De volgende afschrijving mislukte. De sessie eindigt op een minuutgrens en wordt opgeslagen. |
idle_timeout | 5 minuten geen audio. |
max_duration | De sessie was 300 minuten verbonden. Start een nieuwe. |
disconnected | De client was langer dan 2 minuten weg zonder te hervatten. |
upstream_error | De spraakprovider faalde. |
internal_error | Er ging iets mis aan onze kant. |
not_connected | De sessie kreeg binnen 5 minuten nooit verbinding. Hij wordt nooit in rekening gebracht en is alleen zichtbaar via GET. |
Sluitcodes
| Code | Betekenis |
|---|---|
1000 | Normale sluiting. Komt altijd na session.ended. |
1011 | Onverwachte serverfout. De server herstelt de sessie: hervat met een nieuw token. |
1012 | Serverherstart. Komt na reconnect: hervat met een nieuw token. |
4001 | Het token is ongeldig, verlopen of al gebruikt. |
4004 | De sessie is niet gevonden of is al afgelopen. |
4008 | Protocolschending: een binair frame met oneven lengte of dat te groot is. |
4010 | Vervangen door een nieuwere verbinding met dezelfde sessie. |
Terwijl de API herstart, kan een nieuw WebSocket-verzoek met HTTP 503 worden beantwoord. Probeer het zo opnieuw.
Hervatten en overnemen
Een sessie overleeft een verbroken netwerk, een API-deploy en een crash. Na een verbreking wacht hij 2 minuten op je; daarna eindigt hij als disconnected en wordt hij opgeslagen.
- Roep
POST /v1/live/sessions/:id/tokenaan. Het antwoord bevattoken,token_expires_atenwebsocket_url, dezelfde velden als bij het aanmaken van de sessie. Het mislukt met409 session_endedzodra de sessie is afgelopen. - Open een nieuwe WebSocket met dat token.
session.startedkomt binnen metresumed: true.offset_msis de hoeveelheid audio die de sessie al heeft verwerkt: ga vanaf dat punt verder met de audio. De regel-id's lopen door.
Regels die al definitief waren, blijven bewaard. De onafgeronde staart op het moment van de verbreking gaat verloren, dus speel een paar seconden audio vanaf offset_ms opnieuw af als je die buffert. Gaten tijdens het heraansluiten worden niet in rekening gebracht.
Overnemen is dezelfde aanroep. Denkt de server nog dat een socket openstaat, dan vervangt een nieuwe geldige verbinding die, en wordt de oude socket gesloten met 4010 nadat zijn regels zijn opgeslagen. Een hervatting wordt nooit geblokkeerd door de limiet voor gelijktijdige sessies.
De SDK doet dit allemaal voor je: bij een verbreking of een reconnect-event haalt hij een token op en verbindt hij opnieuw met een backoff van 0,5 tot 8 seconden, tot 2 minuten lang, en speelt hij de laatste 10 seconden audio die tijdens het gat zijn verstuurd opnieuw af.
Facturatie
Live transcriptie gebruikt hetzelfde minutensaldo als batchtranscripties.
- Verbonden tijd wordt in rekening gebracht, vanaf het moment dat de socket wordt geaccepteerd tot hij sluit. Stilte en een gepauzeerde video tellen mee. De tijd tussen een verbreking en een hervatting niet.
- Per gestarte minuut, minimaal 1. De eerste minuut wordt afgeschreven als de eerste verbinding wordt geaccepteerd, en elke volgende minuut als die begint.
- Sneller dan realtime wordt als audiotijd gerekend. Als de audio die je stuurt langer is dan de verbonden tijd, wordt de audiotijd gerekend.
- De rate lees je uit de API. Eén gestarte minuut kost
ratesaldominuten, naar boven afgerond. De rate is meestal 1 en kan decimalen hebben. Lees de live rate uitrates.liveinGET /v1/account, uitrateinGET /v1/live/capabilitiesen uitratein de sessie die je aanmaakt. De rate van een sessie staat vast zodra hij is aangemaakt. - Vertalen is gratis.
- Nooit verbonden betekent niet in rekening gebracht. Een sessie die binnen 5 minuten geen verbinding krijgt, eindigt als
not_connected. - Mislukkingen worden terugbetaald. Als een sessie eindigt met
upstream_errorofinternal_errorvoordat hij één regel heeft opgeleverd, worden alle afschrijvingen teruggegeven. Een lege sessie door stilte wordt wel in rekening gebracht en leeg opgeslagen. - Als het saldo op is en automatisch opwaarderen aanstaat, belast transcript1 je opgeslagen kaart terwijl de sessie blijft streamen, en gaat de sessie door. Staat automatisch opwaarderen uit of gepauzeerd, of mislukt de afschrijving, dan wordt de sessie afgerond, opgeslagen en beëindigd met
balance_exhaustedop een minuutgrens. De waarschuwingbalance_lowkomt eerst, tenzij automatisch opwaarderen aanstaat.
Een sessie aanmaken geeft 402 insufficient_minutes als je bruikbare saldo lager is dan één gestarte minuut tegen de huidige rate. Staat automatisch opwaarderen aan, dan probeert transcript1 eerst op te waarderen. Zie Facturatie en limieten.
Limieten
| Free | Monthly | Annual | |
|---|---|---|---|
| Gelijktijdige live sessies | 1 | 2 | 3 |
- Een sessie telt mee zolang hij
waiting,connectedofdisconnectedis (binnen zijn venster van 2 minuten). Boven de limiet geeftPOST /v1/live/sessions429 too_many_live_sessionsmetRetry-After: 30. - Live sessies tellen niet mee voor je limiet voor actieve jobs.
- Een sessie duurt maximaal 300 minuten verbonden tijd. Daarna eindigt hij met
max_duration. - Een sessie zonder audio gedurende 5 minuten eindigt met
idle_timeout; na 4 minuten krijg jeidle_timeout_soon. Een gepauzeerde stream kost nog steeds verbonden tijd en telt als inactief, dus beëindig de sessie als de pauze lang duurt. - transcript1 begrenst ook alle live sessies samen. Zijn ze allemaal in gebruik, dan geeft
POST /v1/live/sessions503 live_capacity, wat je opnieuw mag proberen. Wacht opRetry-After(30 seconden) en probeer het nog eens. Dit wordt alleen gecontroleerd bij het aanmaken van een sessie, nooit midden in een sessie. - Sessies aanmaken en tokens ophalen tellen mee voor je requests per minuut.
- Audio is alleen ruwe PCM:
pcm_s16le, mono, 8000 tot 48000 Hz.
Mogelijkheden
GET /v1/live/capabilities beschrijft wat live transcriptie op dit moment ondersteunt, zodat clients nooit regels van de provider hard hoeven te coderen. De scope is 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
}De lijsten zijn hier ingekort. Lees ze uit de API.
translation.pairsis"any"(elke gedetecteerde taal naar elke doeltaal), of een lijst objecten metfromento.translation.requires_languageistrueals vertalen een explicietelanguagenodig heeft in plaats vanauto.- Als live transcriptie niet is geconfigureerd, is het antwoord
available: falsemet alleenrate, en geeft een sessie aanmaken503 live_unavailable.
Met de SDK: await t1.live.capabilities().
Een sessie opvragen
GET /v1/live/sessions/:id geeft de status van een sessie terug. De scope is 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 is waiting, connected, disconnected of ended. end_reason is null totdat de sessie is afgelopen. Met de SDK: await t1.live.get(id).
Fouten
Requestfouten gebruiken de gebruikelijke foutenvelop. Dit zijn de fouten die POST /v1/live/sessions en de bijbehorende endpoints teruggeven:
| HTTP-status | code | Opnieuw proberen | Wanneer |
|---|---|---|---|
| 422 | invalid_request | Nee | Een veld ontbreekt of is ongeldig, bijvoorbeeld een sample_rate buiten 8000 tot 48000. |
| 422 | unsupported_language | Nee | language wordt niet ondersteund voor live transcriptie. |
| 422 | unsupported_translation | Nee | De doeltaal, of het taalpaar, wordt niet ondersteund. |
| 402 | insufficient_minutes | Nee | Je bruikbare saldo is lager dan één gestarte minuut tegen de huidige rate. |
| 403 | email_not_verified | Nee | Bevestig eerst je e-mailadres. |
| 429 | too_many_live_sessions | Ja | De gelijktijdige live sessies van je abonnement zijn in gebruik. Wacht op Retry-After. |
| 503 | live_capacity | Ja | Alle live capaciteit is in gebruik. Wacht op Retry-After (30 seconden). |
| 503 | live_unavailable | Nee | Live transcriptie is op dit moment niet beschikbaar. |
| 409 | session_ended | Nee | POST /v1/live/sessions/:id/token voor een sessie die is afgelopen. |
Problemen op de socket komen binnen als error-events en sluitcodes.
Opgeslagen transcripten
Met save: true (de standaard) wordt de sessie bij het einde opgeslagen als een gewone transcriptie. De audio wordt nooit bewaard.
transcription_idkrijg je terug als je de sessie aanmaakt. De status islivezolang de sessie loopt encompletederna. Een sessie die nooit verbinding kreeg, laat een transcriptie met statuscanceledachter.- De transcriptie heeft
source: { "platform": "live", "session_id": "lv_…" }. Er is geen link of bestand. Het dashboard toont haar als live sessie. - Elke regel wordt één segment, met dezelfde index als de
idvan de regel. Lees het transcript als JSON, tekst, SRT of VTT zoals bij elke andere transcriptie: zie de API-referentie. - De live vertaling wordt mee opgeslagen. Lees hem met de parameter
translation, zoals beschreven bij Vertalen. - Voeg later meer vertaaltalen toe met
POST /v1/transcriptions/:id/translationszodra de transcriptiecompletedis. Zie Vertalen.
Met save: false blijft er niets bewaard nadat de sessie is afgelopen: er is geen transcriptie en transcription_id is null. Je krijgt nog wel elke regel via de socket en de gebruikelijke afschrijving geldt.
Beveiliging
- Het token dat je krijgt als je een sessie aanmaakt, is eenmalig en verloopt na 60 seconden. Het wordt als WebSocket-subprotocol verstuurd en niet in de URL, zodat het buiten toegangslogs blijft. Een gelekt token is nutteloos zodra het is gebruikt of verlopen.
- Gebruik een API-sleutel alleen vanaf een server die je zelf beheert. Zet nooit een API-sleutel in een webpagina of een extensie.
- Laat gebruikers in een browser of extensie inloggen met OAuth en geef het OAuth-toegangstoken door aan
getAccessTokenvancreateLiveClient. Het token heeft de scopetranscriptions:writenodig om sessies te starten. OAuth-toegangstokens verlopen na 1 uur en bij elke hervatting vraagt de SDKgetAccessTokenom een nieuw token. - Je server kan de sessie ook met zijn API-sleutel aanmaken en alleen de
websocket_urlen hettokenaan de browser geven. De client verbindt dan direct. Zonder nieuw token van jou kan hij niet hervatten.
Laatst bijgewerkt 3 november 2026