9.7 KiB
Audio Transcription API Documentation
OpenAI-compatible speech-to-text transcription API using faster-whisper.
Base URL
{BASE_URL}
- Local development:
http://localhost:8200 - Docker (internal):
http://audio-api:8200 - Direct:
http://localhost:54300 - Production: Use your configured hostname
Authentication
No authentication required by default. Can be added via nginx or API gateway if needed.
API Endpoints
Health Check
Check API health status.
Endpoint: GET /health
Response:
{
"status": "ok"
}
Example:
curl http://localhost:8200/health
List Models
List available Whisper models (OpenAI-compatible).
Endpoint: GET /v1/models
Response:
{
"object": "list",
"data": [
{
"id": "large-v3-turbo",
"object": "model",
"created": 1700000000,
"owned_by": "openai"
}
]
}
Example:
curl http://localhost:8200/v1/models
Create Transcription
Transcribe audio file to text (OpenAI-compatible endpoint).
Endpoint: POST /v1/audio/transcriptions
Content-Type: multipart/form-data
Request Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
file |
file | Yes | - | Audio file to transcribe (MP3, WAV, M4A, etc.) |
model |
string | No | large-v3-turbo |
Model to use (currently ignored, uses configured model) |
language |
string | No | null |
Language code (ISO-639-1). Auto-detected if not specified. |
prompt |
string | No | null |
Optional text to guide the model's style |
response_format |
string | No | json |
Format: json, text, or verbose_json |
temperature |
float | No | 0.0 |
Sampling temperature (0.0-1.0). Use 0.0 for deterministic output. |
Supported Languages (ISO-639-1 codes):
en, es, fr, de, it, pt, nl, pl, tr, ru, ja, ko, zh, ar, hi, and 90+ more languages.
Response Formats:
1. JSON (default)
{
"text": "Full transcription text",
"language": "en",
"duration": 45.5
}
2. Text
Full transcription text
3. Verbose JSON
{
"text": "Full transcription text",
"language": "en",
"duration": 45.5,
"segments": [
{
"id": 0,
"seek": 0,
"start": 0.0,
"end": 3.5,
"text": "Hello, world!",
"tokens": [15496, 11, 1002, 0],
"temperature": 0.0,
"avg_logprob": -0.25,
"compression_ratio": 1.5,
"no_speech_prob": 0.01
}
]
}
Examples:
Basic transcription (JSON):
curl -X POST "http://localhost:8200/v1/audio/transcriptions" \
-F "file=@audio.mp3" \
-F "response_format=json"
With language specification:
curl -X POST "http://localhost:8200/v1/audio/transcriptions" \
-F "file=@audio.mp3" \
-F "language=en" \
-F "response_format=json"
Text format:
curl -X POST "http://localhost:8200/v1/audio/transcriptions" \
-F "file=@audio.mp3" \
-F "response_format=text"
Verbose JSON with segments:
curl -X POST "http://localhost:8200/v1/audio/transcriptions" \
-F "file=@audio.mp3" \
-F "response_format=verbose_json"
With initial prompt (to guide style):
curl -X POST "http://localhost:8200/v1/audio/transcriptions" \
-F "file=@audio.mp3" \
-F "prompt=This is a technical discussion about machine learning." \
-F "response_format=json"
Python example:
import requests
url = "http://localhost:8200/v1/audio/transcriptions"
with open("audio.mp3", "rb") as f:
files = {"file": f}
data = {
"model": "large-v3-turbo",
"language": "en",
"response_format": "verbose_json"
}
response = requests.post(url, files=files, data=data)
result = response.json()
print(f"Transcription: {result['text']}")
print(f"Duration: {result['duration']}s")
print(f"Segments: {len(result['segments'])}")
JavaScript example:
const formData = new FormData();
formData.append('file', audioFile);
formData.append('model', 'large-v3-turbo');
formData.append('response_format', 'json');
const response = await fetch('http://localhost:8200/v1/audio/transcriptions', {
method: 'POST',
body: formData
});
const result = await response.json();
console.log('Transcription:', result.text);
Error Responses
Standard Error Format
{
"detail": "Error message"
}
Common HTTP Status Codes
| Code | Meaning | Description |
|---|---|---|
| 200 | OK | Request successful |
| 400 | Bad Request | Invalid request parameters |
| 413 | Payload Too Large | File exceeds max size limit (default 500MB) |
| 422 | Unprocessable Entity | Invalid file format or corrupted audio |
| 500 | Internal Server Error | Transcription failed |
| 503 | Service Unavailable | Model not loaded or GPU unavailable |
Example error response:
{
"detail": "File too large: 550.0MB (max: 500MB)"
}
Rate Limiting
No built-in rate limiting. Can be added via nginx or API gateway.
Recommended nginx configuration:
limit_req_zone $binary_remote_addr zone=audio_limit:10m rate=10r/m;
location / {
limit_req zone=audio_limit burst=5;
proxy_pass http://audio-api:8200;
}
File Size Limits
- Default: 500MB per file
- Configurable via:
AUDIO_MAX_FILE_SIZE_MBenvironment variable - Recommended: Keep files under 100MB for best performance
Supported Audio Formats
All formats supported by FFmpeg, including:
Audio files:
- MP3, WAV, FLAC, OGG, M4A, AAC, WMA, OPUS
Video files (audio track extraction):
- MP4, AVI, MKV, MOV, WEBM, FLV
Professional formats:
- PCM, AIFF, AU, AMR
Performance Considerations
Processing Time
Approximate transcription times for large-v3-turbo with int8 on H200 GPU:
| Audio Length | Processing Time | Real-Time Factor |
|---|---|---|
| 1 minute | ~3-5 seconds | 0.05-0.08x |
| 10 minutes | ~30-50 seconds | 0.05-0.08x |
| 1 hour | ~3-5 minutes | 0.05-0.08x |
Real-Time Factor (RTF): Processing time / Audio duration. Lower is better.
- RTF < 0.1x = Excellent (8x faster than real-time)
- RTF < 0.5x = Good (2x faster than real-time)
- RTF = 1.0x = Real-time
Optimization Tips
- Use language parameter when known (skip auto-detection)
- Use appropriate model size based on accuracy needs
- Process shorter segments for long recordings (split at silence)
- Monitor GPU utilization with
nvidia-smi
Comparison with OpenAI API
This API is fully compatible with OpenAI's transcription endpoint:
| Feature | OpenAI | This API |
|---|---|---|
| Endpoint | /v1/audio/transcriptions |
/v1/audio/transcriptions ✅ |
| Request format | multipart/form-data |
multipart/form-data ✅ |
| Response formats | json, text, verbose_json |
json, text, verbose_json ✅ |
| Language detection | Auto | Auto ✅ |
| Max file size | 25MB | 500MB (configurable) ✅ |
| Cost | $0.006/minute | Free (self-hosted) ✅ |
| Latency | Variable | ~0.05-0.08x RTF ✅ |
Drop-in replacement: Change only the base URL to switch from OpenAI to this API.
SDK Examples
OpenAI Python SDK
from openai import OpenAI
# Point to local API
client = OpenAI(
api_key="not-needed", # No auth required
base_url="http://localhost:8200/v1"
)
with open("audio.mp3", "rb") as f:
transcript = client.audio.transcriptions.create(
model="large-v3-turbo",
file=f,
response_format="verbose_json"
)
print(transcript.text)
OpenAI Node.js SDK
import OpenAI from 'openai';
import fs from 'fs';
const openai = new OpenAI({
apiKey: 'not-needed',
baseURL: 'http://localhost:8200/v1'
});
const transcription = await openai.audio.transcriptions.create({
file: fs.createReadStream('audio.mp3'),
model: 'large-v3-turbo',
response_format: 'verbose_json'
});
console.log(transcription.text);
Advanced Features
Voice Activity Detection (VAD)
Enabled by default. Automatically skips silence for:
- Faster processing
- Better accuracy
- Smaller output
Beam Search
Configurable via AUDIO_BEAM_SIZE (default: 5). Higher values = better accuracy but slower.
Temperature Sampling
0.0(default): Deterministic output0.0-1.0: More creative/diverse outputs (less reliable)
Monitoring
Health Check
# Check if API is ready
curl http://localhost:8200/health
# Expected response
{"status": "ok"}
Logs
# View real-time logs
cd deploy/
docker compose logs -f audio-api
# Check for errors
docker compose logs audio-api | grep ERROR
GPU Usage
# Monitor GPU while transcribing
watch -n 1 nvidia-smi
# Check VRAM usage
nvidia-smi --query-gpu=memory.used,memory.total --format=csv
Troubleshooting
Error: File too large
Solution: Increase max file size or split audio into smaller chunks:
# Increase limit
AUDIO_MAX_FILE_SIZE_MB=1000
# Or split with ffmpeg
ffmpeg -i long_audio.mp3 -f segment -segment_time 600 -c copy chunk_%03d.mp3
Error: Transcription failed
Possible causes:
- Corrupted audio file - verify with media player
- Unsupported format - convert to MP3/WAV
- GPU out of memory - use smaller model or CPU mode
- Audio is pure noise/music - Whisper is designed for speech
Slow performance
Check:
- GPU is being used:
docker exec audio-api nvidia-smi - Model is correct: Check logs for model loading messages
- Compute type is int8: Faster than float16
For more information, see README.md and the faster-whisper documentation.