BizCrush

BizCrush API

Standalone APIs for real-time and batch speech recognition, text-to-speech, audio noise reduction, and text translation.

Automatic language detection across 60 languages — no configuration required. Just send audio and get results.

Use our APIs to build voice-powered apps and translation workflows.

Beta This API is currently in beta. Endpoints and behavior may change without prior notice.

Get Your API Key

An API key is required to use BizCrush APIs. You can create up to 5 keys from your account settings.

Get API Key

Speech-to-Text API

Featured

Speech-to-Text API for audio transcription with speaker diarization. Supports file-based (batch) and real-time (streaming) transcription.

Build Your Own STT Service

Use the BizCrush STT API to build your own speech-to-text service. Integrate real-time transcription into your apps, process audio files at scale, or create custom voice-powered workflows — all with speaker diarization and multi-language support.

Automatic language detection across 60 languages — no configuration required. Just send audio and get results.

Overview

Base URL https://extapi.bizcrush.ai/v1

Authentication

All STT requests require an API key passed as a query parameter:

?api_key=YOUR_API_KEY

You can issue your API key at bizcru.sh/settings.

File STT

Send an audio file URL and receive the full transcript with speaker diarization.

POST /stt Auth: ?api_key

Transcribe an audio file URL and return the full transcript with speaker diarization.

Request Body (JSON)

Name Type Required Description
audio_url string required Public audio file URL (signed URL, CDN URL, etc.)
session_id string optional Session identifier. Auto-generated if omitted
enable_diarization boolean optional Enable speaker diarization (default: true)
language_hints string[] optional Language codes, e.g. ["ko","en"] or "ko,en". Up to 3; extras dropped. Omit for auto-detection. Legacy `language_hint` (single string) also accepted.
context_keywords string[] optional Domain keywords/terms to bias recognition toward names, jargon, etc., e.g. ["Albert Gee","BizCrush"] or "Albert Gee,BizCrush". Up to 2000 characters total; extras dropped.

Response Fields

Field Type Description
text string Full transcript text
detected_language string Detected language code
confidence float Average confidence (0~1)
utterances array Speaker-diarized utterance segments
utterances[].speaker string Speaker number ("0", "1", "2", ...)
utterances[].text string Utterance text
utterances[].start_ms integer Start time (milliseconds)
utterances[].end_ms integer End time (milliseconds)
utterances[].confidence float Utterance confidence
utterances[].language string Utterance language

Response Example

{
  "text": "Could you introduce yourself and tell us about your role?",
  "detected_language": "en",
  "confidence": 0.961,
  "utterances": [
    {
      "speaker": "1",
      "text": "Could you introduce yourself and tell us about your role?",
      "start_ms": 960,
      "end_ms": 5400,
      "confidence": 0.94,
      "language": "en"
    },
    {
      "speaker": "2",
      "text": "Sure. My name is Ethan Kim, and I'm CTO of BizCrush.",
      "start_ms": 5820,
      "end_ms": 9600,
      "confidence": 0.96,
      "language": "en"
    }
  ]
}

cURL Example

curl -X POST \
  "https://extapi.bizcrush.ai/v1/stt?api_key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"audio_url": "https://example.com/audio.oga", "enable_diarization": true}'

Note: Response time depends on audio length — may take up to several minutes. Set timeout to 600+ seconds.

Live STT (WebSocket)

Real-time audio streaming transcription via WebSocket. Send audio chunks and receive interim/final results in real time.

WS wss://extapi.bizcrush.ai/v1/stt/stream

Query Parameters

Name Type Required Description
api_key string required API key
format string optional "json" for JSON text frames, omit for protobuf binary
reduce_noise string optional "true" to enable real-time noise reduction
language_hints string[] optional Language codes as comma-separated (?language_hints=ko,en) or repeated (?language_hints=ko&language_hints=en). Up to 3; extras dropped. Omit for auto-detection.
enable_diarization string optional Speaker diarization toggle. "false" to disable; enabled by default. When enabled, each chunk carries a speaker label.

Protocol

1 Send Config

Send a JSON text frame with encoding and optional session_id

Field Type Description
encoding string "pcm16" or "opus" (default: "pcm16")
session_id string Session identifier (optional, auto-generated if omitted)
language_hints string[] Optional language codes, e.g. ["ko","en"] or "ko,en". Up to 3 entries; extras dropped. Overrides query param. Omit for auto-detection.
enable_diarization boolean Speaker diarization toggle (default: true). Overrides the query param.
context_keywords string[] Domain keywords/terms to bias recognition toward names, jargon, etc., e.g. ["Albert Gee","BizCrush"] or "Albert Gee,BizCrush". Up to 2000 characters total; extras dropped.
{"encoding": "pcm16", "session_id": "optional-session-id"}
2 Receive Connection Status

Server responds with connection status

{"connected": true}
3 Stream Audio

Send raw audio as binary WebSocket frames

Encoding Format Chunk Size
pcm16 16kHz, mono, 16-bit little-endian 640 bytes (20ms) recommended
opus 16kHz, mono. Raw Opus packets or OGG/Opus container Opus frame unit
4 Receive Transcription Results

Server sends interim and final results as JSON text frames

Field Type Description
chunk.id string Chunk ID — same across interim/final for one utterance, new ID after final
chunk.session_id string Session ID
chunk.text string Transcribed text (cumulative — each interim contains full text so far)
chunk.is_final boolean false: interim result, true: final confirmed result
chunk.speaker string Speaker label ("0", "1", "2", ...) when diarization is enabled. Omitted when disabled or the speaker is unresolved.
{"chunk": {"id": "01KMCHP57H31XYZABC", "session_id": "my-session", "text": "Hello, how are you?", "is_final": true, "speaker": "1"}}
5 Signal End-of-Audio (required for clean shutdown)

When no more audio will be sent, send an empty binary frame (0 bytes) and KEEP THE WEBSOCKET OPEN. The server finalizes any pending utterances (including ones still in interim state), streams the trailing is_final results back, then closes the WebSocket. Closing the WebSocket without this marker drops the trailing finals — WebSocket has no half-close, so once the client closes the server cannot deliver the remaining results. Finalize completes within ~5 seconds after the EOS marker. After the trailing finals the server sends a terminal frame ({"finished": true} for JSON, disconnect_reason=SESSION_ENDED for protobuf) and then closes.

ws.send(b'')                  # Python
ws.send(new ArrayBuffer(0));  // JavaScript

Examples

Python

import asyncio
import json
import websockets

async def live_stt(api_key: str):
    url = f"wss://extapi.bizcrush.ai/v1/stt/stream?api_key={api_key}&format=json"

    async with websockets.connect(url) as ws:
        await ws.send(json.dumps({"encoding": "pcm16"}))

        resp = json.loads(await ws.recv())
        assert resp["connected"], f"Connection failed: {resp}"

        async def send_audio():
            with open("audio.pcm", "rb") as f:
                while chunk := f.read(640):
                    await ws.send(chunk)
                    await asyncio.sleep(0.02)
            # End-of-audio marker. DO NOT close the WebSocket here — the
            # server needs the connection open to deliver trailing finals.
            # The server will close after finalize completes (~5 seconds).
            await ws.send(b'')

        async def receive_results():
            try:
                async for msg in ws:
                    data = json.loads(msg)
                    if "chunk" in data:
                        chunk = data["chunk"]
                        status = "FINAL" if chunk["is_final"] else "interim"
                        speaker = chunk.get("speaker", "?")
                        print(f"[{status}] (S{speaker}) {chunk['text']}")
            except websockets.exceptions.ConnectionClosed:
                pass

        await asyncio.gather(send_audio(), receive_results())

asyncio.run(live_stt("YOUR_API_KEY"))

JavaScript (Browser)

const ws = new WebSocket(
  "wss://extapi.bizcrush.ai/v1/stt/stream?api_key=YOUR_API_KEY&format=json"
);

ws.onopen = () => {
  ws.send(JSON.stringify({ encoding: "pcm16" }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);

  if (data.connected) {
    console.log("Connected! Start sending audio...");
  }

  if (data.chunk) {
    const { id, text, is_final, speaker } = data.chunk;
    console.log(`[${is_final ? "FINAL" : "interim"}] (S${speaker ?? "?"}) ${text}`);
  }
};

// Server closes the WebSocket after delivering trailing finals.
ws.onclose = () => {
  console.log("Stream finalized by server");
};

function sendAudioChunk(pcmData) {
  if (ws.readyState === WebSocket.OPEN) {
    ws.send(pcmData);
  }
}

// Call this when you have no more audio to send.
// DO NOT call ws.close() — the server needs the socket open to deliver
// trailing finals, then closes it itself (~5 seconds).
function endStream() {
  if (ws.readyState === WebSocket.OPEN) {
    ws.send(new ArrayBuffer(0));  // end-of-audio marker
  }
}

Text-to-Speech (TTS)

Convert text to natural-sounding speech and receive a signed download URL (audio uploaded to Firebase Storage).

POST /tts Auth: ?api_key

Generate speech audio from text and return a signed download URL (audio uploaded to Firebase Storage at tts/{session_id}/{message_id}.ogg).

Request Body (Protobuf)

application/x-protobuf (request and response are protobuf-encoded SessionTTSRequest / SessionTTSResponse)

Name Type Required Description
session_id string required Session identifier
message_id string required Message identifier (used in storage path)
text string required Text to convert to speech

Response Fields

Field Type Description
audio_url string Signed download URL (Opus / OGG) — valid for several days
error string Set on failure; audio_url empty
Audio Format
OGG/Opus, single channel
Default Voice
nova (configurable server-side)

TTS Supported Languages

Text-to-speech generates natural-sounding audio across 57 languages. The language is detected automatically from the input text — no configuration required.

Code Language
en English
zh 中文
hi हिन्दी
es Español
ar العربية
fr Français
pt Português
ru Русский
id Bahasa Indonesia
de Deutsch
ja 日本語
vi Tiếng Việt
it Italiano
ko 한국어
th ภาษาไทย
af Afrikaans
hy Հայերեն
az Azərbaycan
be Беларуская
bs Bosanski
bg Български
ca Català
hr Hrvatski
cs Čeština
da Dansk
nl Nederlands
et Eesti
fi Suomi
gl Galego
el Ελληνικά
he עברית
hu Magyar
is Íslenska
kn ಕನ್ನಡ
kk Қазақ
lv Latviešu
lt Lietuvių
mk Македонски
ms Bahasa Melayu
mi Te Reo Māori
mr मराठी
ne नेपाली
no Norsk
fa فارسی
pl Polski
ro Română
sr Српски
sk Slovenčina
sl Slovenščina
sw Kiswahili
sv Svenska
tl Tagalog
ta தமிழ்
tr Türkçe
uk Українська
ur اردو
cy Cymraeg

Audio Noise Reduction

Remove background noise from audio files using BizCrush AI. Provide a download URL and receive a denoised M4A file.

POST /v1/denoise X-API-Key

Denoise an audio file using BizCrush AI. Provide a download URL; the server applies noise reduction, re-encodes to M4A (AAC), and returns a signed download URL valid for 1 hour.

Request Body

Name Type Required Description
audio_url string required Input audio file download URL (any format supported by ffmpeg)
atten_limit_db number optional Noise attenuation limit in dB. 0 uses the server default; higher values are stronger (0-100)
disable_adaptive_mix boolean optional Use fixed attenuation for a stronger effect; may damage speech (default: false)

Response Fields

Field Type Description
denoised_audio_url string Signed download URL for the denoised M4A file (valid ~1 hour)
applied_atten_db number Average attenuation limit actually applied
frame_lsnr_db number[] Frame-level local SNR measurements

Supported Languages

Automatic language detection is built in — no configuration needed. The STT engine detects and transcribes across 60 languages seamlessly, even when speakers switch languages mid-conversation. Optionally use language_hint for faster detection.

Code Language
en English
zh 中文
hi हिन्दी
es Español
ar العربية
fr Français
pt Português
ru Русский
id Bahasa Indonesia
de Deutsch
ja 日本語
vi Tiếng Việt
it Italiano
ko 한국어
th ภาษาไทย
af Afrikaans
sq Shqip
az Azərbaycan
eu Euskara
be Беларуская
bn বাংলা
bs Bosanski
bg Български
ca Català
hr Hrvatski
cs Čeština
da Dansk
nl Nederlands
et Eesti
fi Suomi
gl Galego
el Ελληνικά
gu ગુજરાતી
he עברית
hu Magyar
kn ಕನ್ನಡ
kk Қазақ
lv Latviešu
lt Lietuvių
mk Македонски
ms Bahasa Melayu
ml മലയാളം
mr मराठी
no Norsk
fa فارسی
pl Polski
pa ਪੰਜਾਬੀ
ro Română
sr Српски
sk Slovenčina
sl Slovenščina
sw Kiswahili
sv Svenska
tl Tagalog
ta தமிழ்
te తెలుగు
tr Türkçe
uk Українська
ur اردو
cy Cymraeg

STT Error Codes

Status Error Description
401 Missing authorization API key not provided
401 Invalid API key Invalid API key
400 Empty request body Request body is empty
400 Missing audio_url audio_url field missing (File STT)
400 Missing session_id, message_id, or text Required TTS field missing
400 Invalid JSON JSON parsing failed
500 TTS generation failed OpenAI TTS call failed
500 Storage upload failed Firebase Storage upload failed
500 (varies) Internal server error (transcription failure, etc.)
WS 1008 Auth failure WebSocket closed with code 1008 on authentication failure

Text Translation

Translate plain text into multiple target languages with BizCrush AI.

POST /v1/translate-text

Translate plain-text input while preserving document formatting.

Parameters

Name Type Required Description
text str required Plain text to translate (up to 100,000 characters by default)
target_languages list[str] required Target language codes or names, such as ["ko", "en", "Japanese"] (up to 10)
source_language str optional Source language code or name (default: auto)