SDKs
Official client SDKs are available for Python and TypeScript/Node. Both cover
the full API: instant and demand streaming over the /audio/v1/listen
WebSocket, whole-file transcription over POST /audio/v1/transcribe, async
transcription jobs over POST /audio/v1/transcriptions, PII redaction, keyword
boosting, word timestamps, and transcript assembly helpers. Source, full guides,
and runnable examples live in the
bw_labs_sdks repository. The
TypeScript SDK is available from npm, and the Python SDK is available from PyPI.
Create an API key from your dashboard and set it as
BW_STT_API_KEY in your environment; both SDKs pick it up automatically.
Install
Once version 0.2.0 is on PyPI, install the Python SDK with:
pip install bw-stt
The repository install remains available as an alternative:
git clone https://github.com/Bandwidth/bw_labs_sdks.git
pip install ./bw_labs_sdks/python
TypeScript/Node, install from npm:
npm install @bandwidth-labs/bw-stt@^0.2.0
Live transcription (instant mode)
Stream audio and print words as they land. Segments are final the moment they arrive; the assembler joins them into a running transcript.
from bw_stt import BwSttClient, TranscriptAssembler
client = BwSttClient()
transcript = TranscriptAssembler()
with client.connect(encoding="linear16", sample_rate=16000) as session:
session.on_segment(transcript.push)
for _segment in session.stream_file("call.wav"):
print("\r" + transcript.text, end="", flush=True)
closed = session.close_stream()
print("\r" + transcript.text)
import { BwSttClient } from "@bandwidth-labs/bw-stt";
const client = new BwSttClient();
const session = await client.connect({ encoding: "linear16", sampleRate: 16000 });
session.on("segment", (segment) => process.stdout.write(segment.text));
for await (const segment of session.streamFile("call.wav")) void segment;
await session.closeStream();
Transcripts on your schedule (demand mode)
In demand mode nothing is delivered until you ask. Stream audio, then call the finalize helper at each boundary you care about, such as the end of a caller turn. Each call returns one finalized transcript per channel.
with client.connect(mode="demand") as session:
session.send_audio(turn_audio)
transcripts = session.finalize_transcript() # one Transcript per channel
print(transcripts[0].text)
const session = await client.connect({ mode: "demand" });
session.sendAudio(turnAudio);
const transcripts = await session.finalizeTranscript();
console.log(transcripts[0].text);
Whole recordings (Transcribe)
One call for a complete recording of up to five minutes. The result carries the full text, word timestamps, and segments.
result = client.transcribe("call.wav")
print(result.text)
for word in result.words[:5]:
print(word.word, word.start, word.end)
import { readFile } from "node:fs/promises";
const result = await client.transcribe(await readFile("call.wav"));
console.log(result.text);
Long recordings (async transcription)
For recordings over five minutes and up to 30 minutes, submit an asynchronous
job. Use get for the current status, wait to poll until the job reaches a
terminal status, and delete to remove the job and its stored result.
job = client.transcriptions.submit("call.wav")
current = client.transcriptions.get(job.id) # TranscriptionJob: status, progress
result = client.transcriptions.wait(job.id) # Transcription; raises TranscriptionJobError if the job fails
print(result.text)
client.transcriptions.delete(job.id)
import { readFile } from "node:fs/promises";
const job = await client.transcriptions.submit({ audio: await readFile("call.wav"), raw: false });
const current = await client.transcriptions.get(job.id);
const result = await client.transcriptions.wait(job.id);
console.log(result.text);
await client.transcriptions.delete(job.id);
wait polls every 2 seconds and gives up after 600 seconds by default, raising
TranscriptionTimeoutError; both values are configurable. Uploads are buffered
in memory before sending, up to the 512 MiB limit. Raw audio submitted with
multichannel=true must declare channels=2; WAV files and audio_url
submissions let the service read the channel count itself.
Redaction and keywords
Both SDKs expose the PII and keyword options as typed parameters on connect
and transcribe. Redaction is available in demand and Transcribe modes.
result = client.transcribe(
"call.wav",
redact_pii=True,
redact_pii_return=True,
keywords=["Bandwidth", "porting"],
)
for entity in result.redacted_entities:
print(entity.kind, entity.token, entity.text)
const result = await client.transcribe(audio, {
redactPii: true,
redactPiiReturn: true,
keywords: ["Bandwidth", "porting"],
});
For event handling, error taxonomy, browser usage, codec options, and complete examples, see the language guides in the repository.