Upload an audio file and receive a text transcript, or stream a microphone to Parakeet for interim and final events. Parakeet is the fast default; Qwen3-ASR adds multilingual recognition and alignment; experimental MOSS Transcribe-Diarize jointly emits English/Chinese text, speakers, and segment timestamps.
GET /transcription/models
Lists configured recognition providers, enabled state, language/timestamp capabilities, and whether diarization is built in.
Live Parakeet transcription
WS /v1/realtime/transcription
Streams mono 16 kHz little-endian float32 PCM to Parakeet's native transcribe_stream path. Use wss:// when the page is served over HTTPS. The playground's Start Live Transcription control is a complete browser client.
- Wait for the server's
connected event.
- Send
{"type":"start","encoding":"pcm_f32le","sampleRate":16000}. When global auth is enabled, browser clients also include apiKey in this message; non-browser clients may authenticate in the upgrade headers.
- After
session.started, send binary PCM frames. The recommended cadence is 8,000 samples / 32,000 bytes (0.5 seconds).
- Read
transcript.partial updates. Send {"type":"stop"} for transcript.final, or {"type":"abort"} to discard the stream.
{
"type": "transcript.partial",
"sessionId": "...",
"sequence": 3,
"text": "Realtime transcription is working",
"finalizedText": "Realtime",
"draftText": "transcription is working",
"audioSeconds": 1.5,
"processingSeconds": 0.09,
"realTimeFactor": 0.21
}
{
"type": "transcript.final",
"sessionId": "...",
"text": "Realtime transcription is working.",
"timestamps": [
{ "text": "Realtime", "start": 0.0, "end": 0.4 }
],
"audioSeconds": 1.7,
"realTimeFactor": 0.18
}
Only one Parakeet live stream can own the resident model at a time; a second client receives retryable error code busy and WebSocket close code 1013. Parakeet batch requests pause for the same interval, while Qwen3-ASR and MOSS remain available. Cross-origin upgrades follow CORS_ORIGINS, and the default live limit is five minutes.
POST /transcribe
Request
Send audio as multipart/form-data.
| Parameter |
Type |
Description |
file * |
File |
Audio file to transcribe (supports common formats: mp3, wav, webm, m4a, etc.) |
engine (optional) |
string |
parakeet (default), qwen3, or experimental moss-td |
language (optional) |
string |
Qwen3-ASR language name/code or auto (default). Not accepted by moss-td, which handles English/Chinese automatically. |
timestamps (optional) |
string |
Set to "true" to include sentence-level timings with start/end times for each segment |
wordTimestamps (optional) |
string |
Set to "true" to include word-level timings (overrides timestamps). Not supported by moss-td. |
diarize (optional) |
string |
Set to "true" to identify speakers with pyannote Community-1. MOSS always performs built-in diarization instead. |
numSpeakers (optional) |
string |
Exact speaker count from 1-20. Overrides the minimum and maximum. |
minSpeakers / maxSpeakers (optional) |
string |
Expected speaker-count range from 1-20. |
hotwords / prompt (MOSS only) |
string |
Optional vocabulary hints or a custom transcription instruction for moss-td. |
maxNewTokens (MOSS only) |
string |
Generation limit from 64-65536; raise it for long recordings. |
Response (default)
{
"success": true,
"transcript": "The transcribed text appears here.",
"filename": "recording.mp3"
}
Response (with sentence timestamps)
When timestamps=true, the response includes sentence-level timing data for subtitle generation:
{
"success": true,
"timestamps": [
{ "start": 0.00, "end": 2.34, "text": "Hello and welcome" },
{ "start": 2.34, "end": 5.67, "text": "to our presentation today" },
{ "start": 5.67, "end": 8.90, "text": "we will cover several topics" }
]
}
Response (with word timestamps)
When wordTimestamps=true, the response includes word-level timing data for precise subtitle synchronization:
{
"success": true,
"timestamps": [
{ "start": 0.00, "end": 0.48, "text": "Hello" },
{ "start": 0.48, "end": 0.72, "text": "and" },
{ "start": 0.72, "end": 1.20, "text": "welcome" },
{ "start": 1.20, "end": 1.44, "text": "to" },
{ "start": 1.44, "end": 1.68, "text": "our" },
{ "start": 1.68, "end": 2.34, "text": "presentation" }
]
}
Each timestamp object contains:
start - Start time in seconds
end - End time in seconds
text - The transcribed text (sentence or word depending on mode)
Response (with speaker identification)
{
"success": true,
"timestamps": [
{ "start": 0.00, "end": 1.40, "text": "Welcome.", "speaker": "SPEAKER_00" },
{ "start": 1.50, "end": 2.80, "text": "Thank you.", "speaker": "SPEAKER_01" }
],
"diarization": { "available": true, "numSpeakers": 2 },
"speakers": [
{ "speaker": "SPEAKER_00", "segmentCount": 1, "totalSeconds": 1.4 },
{ "speaker": "SPEAKER_01", "segmentCount": 1, "totalSeconds": 1.3 }
]
}
Qwen3-ASR with word alignment
When Qwen3-ASR receives timestamps=true or wordTimestamps=true, the Qwen3 ForcedAligner generates the requested spans. Alignment supports audio up to 5 minutes in 11 languages.
{
"success": true,
"engine": "qwen3",
"language": "English",
"model": "mlx-community/Qwen3-ASR-0.6B-8bit",
"timestampLevel": "word",
"timestamps": [
{ "text": "Hello", "start": 0.0, "end": 0.4 },
{ "text": "world", "start": 0.4, "end": 0.8 }
]
}
MOSS Transcribe-Diarize (experimental)
This opt-in 0.9B engine performs English/Chinese transcription, diarization, and segment timing in one model pass. It is pinned to reviewed package/model commits, runs in an isolated Python 3.12 environment, and uses local model classes with remote code disabled. Word timestamps, language selection, and speaker-count constraints are not supported.
{
"success": true,
"engine": "moss-td",
"experimental": true,
"transcript": "Good morning. Thanks for joining.",
"segments": [
{ "start": 0.0, "end": 1.2, "speaker": "S01", "text": "Good morning." },
{ "start": 1.25, "end": 2.8, "speaker": "S02", "text": "Thanks for joining." }
],
"diarization": { "available": true, "builtIn": true, "numSpeakers": 2 },
"timestampLevel": "segment"
}
cURL Examples
# Basic transcription
curl -X POST https://voice.sogni.ai/transcribe \
-F "file=@/path/to/audio.mp3"
# With sentence-level timings
curl -X POST https://voice.sogni.ai/transcribe \
-F "file=@/path/to/audio.mp3" \
-F "timestamps=true"
# With word-level timings
curl -X POST https://voice.sogni.ai/transcribe \
-F "file=@/path/to/audio.mp3" \
-F "wordTimestamps=true"
# Experimental one-pass transcript + speakers
curl -X POST https://voice.sogni.ai/transcribe \
-F "file=@/path/to/meeting.wav" \
-F "engine=moss-td" \
-F "hotwords=Sogni, MLX"
# With local speaker identification
curl -X POST https://voice.sogni.ai/transcribe \
-F "file=@/path/to/conversation.mp3" \
-F "timestamps=true" \
-F "diarize=true" \
-F "minSpeakers=2" \
-F "maxSpeakers=4"
# Qwen3-ASR with auto language detection and word alignment
curl -X POST https://voice.sogni.ai/transcribe \
-F "file=@/path/to/speech.m4a" \
-F "engine=qwen3" \
-F "language=auto" \
-F "wordTimestamps=true" \
-F "diarize=false"
Forced Alignment of Known Text
POST /qwen-asr/align
Align an exact transcript to an audio file. Send file, text, and one of the 11 supported language names as multipart fields.
curl -X POST https://voice.sogni.ai/qwen-asr/align \
-F "file=@/path/to/speech.wav" \
-F "text=The exact words spoken in the recording." \
-F "language=English"
{
"success": true,
"language": "English",
"model": "mlx-community/Qwen3-ForcedAligner-0.6B-8bit",
"timestamps": [
{ "text": "The", "start": 0.0, "end": 0.18 },
{ "text": "exact", "start": 0.18, "end": 0.52 }
]
}
JavaScript Example
const formData = new FormData();
formData.append('file', audioFile);
const response = await fetch('https://voice.sogni.ai/transcribe', {
method: 'POST',
body: formData
});
const data = await response.json();
console.log(data.transcript);
Python Example
import requests
with open('audio.mp3', 'rb') as f:
response = requests.post(
'https://voice.sogni.ai/transcribe',
files={'file': f}
)
data = response.json()
print(data['transcript'])