Core APIsAudio transcription
Audio transcription
Whisper-family speech-to-text via multipart upload, with verbose timestamps and SRT/VTT output.
POST /v1/audio/transcriptions is the multipart speech-to-text
endpoint, modelled on OpenAI's Whisper API. The gateway routes to a
Whisper-family model hosted on Scaleway or Tensorix.
At a glance
| Endpoint | POST /v1/audio/transcriptions (multipart) |
| Default model | systran/faster-whisper-large-v3 (Tensorix Frankfurt) |
| Max file size | 25 MB per upload |
| Formats accepted | mp3, wav, m4a, webm, mp4, flac, ogg |
| Response formats | json, text, srt, verbose_json, vtt |
Node example
import { readFileSync } from 'node:fs';
import { createCleverRouter } from '@cleverrouter/sdk';
const cr = createCleverRouter({ apiKey: process.env.CLEVERROUTER_API_KEY! });
const res = await cr.transcribe(
{
name: 'meeting.mp3',
type: 'audio/mpeg',
data: readFileSync('./meeting.mp3'),
},
{
model: 'systran/faster-whisper-large-v3',
language: 'en',
},
);
console.log((res as { text: string }).text);Browser example
async function transcribeFile(file: File) {
const res = await cr.transcribe(file, { language: 'de' });
return (res as { text: string }).text;
}Verbose JSON with timestamps
verbose_json adds segment- and word-level timestamps, plus the
detected language and total duration:
const res = await cr.transcribe(file, {
response_format: 'verbose_json',
timestamp_granularities: ['word', 'segment'],
});
const verbose = res as {
text: string;
language?: string;
duration?: number;
segments?: Array<{ id: number; start: number; end: number; text: string }>;
words?: Array<{ word: string; start: number; end: number }>;
};
console.log(verbose.duration, verbose.segments?.length);Response formats
response_format | Returns | Best for |
|---|---|---|
json (default) | { text: string } | Plain transcripts |
verbose_json | Extended JSON | Segments, words, language ID |
text | string | The transcript only |
srt | string | Subtitle file for video |
vtt | string | WebVTT subtitle format |
Input types
type TranscribeInput =
| File
| Blob
| { name: string; type?: string; data: ArrayBuffer | Uint8Array | Blob };File and Blob are native browser/Bun types. The plain-object form
is convenient when you read bytes from disk in Node — the SDK builds
the multipart body for you.
Options
interface TranscribeOpts {
model?: string; // default: 'systran/faster-whisper-large-v3'
language?: string; // ISO-639-1 hint (e.g. 'en', 'de', 'fr')
prompt?: string; // bias transcription with vocab/context
temperature?: number;
response_format?: 'json' | 'text' | 'srt' | 'verbose_json' | 'vtt';
timestamp_granularities?: Array<'word' | 'segment'>;
provider?: 'scaleway' | 'tensorix';
}cURL
curl https://api.cleverouter.eu/v1/audio/transcriptions \
-H "Authorization: Bearer $CLEVERROUTER_API_KEY" \
-F file=@meeting.mp3 \
-F model=systran/faster-whisper-large-v3 \
-F response_format=verbose_jsonProvider notes
| Model | Provider | Region |
|---|---|---|
systran/faster-whisper-large-v3 | Tensorix | Frankfurt |
openai/whisper-large-v3 | Scaleway | Paris |
No Bedrock audio
Bedrock doesn't expose Whisper in eu-central-1. Audio routes
through Scaleway or Tensorix only.
Common gotchas
- Big files time out. Past ~10 minutes of audio, split the file yourself and merge transcripts. Whisper-large processes faster than realtime on Tensorix, but the upload + buffering on a long file often hits the SDK's 60s default timeout.
- Use
languageif you know it. Auto-detection is good but forcinglanguage: 'de'(or whatever) cuts hallucinations on short or noisy clips. promptis a vocab hint, not a system prompt. Paste names and jargon that should appear in the transcript verbatim.
Related
- Cookbook: voice bot — Whisper → chat → speech.
- Catalog — audio models.
- Providers — Scaleway vs Tensorix.