Quick reference for the most common AssemblyAI errors across transcription, streaming, and LeMUR APIs with real error messages and solutions.
assemblyai package installedError: Authentication error: Invalid API key
Status: 401
Cause: API key is missing, invalid, or revoked.
Solution:
# Verify key is set
echo $ASSEMBLYAI_API_KEY
# Test directly
curl -H "Authorization: $ASSEMBLYAI_API_KEY" \
https://api.assemblyai.com/v2/transcript \
-X GET
{ "status": "error", "error": "Download error: unable to download..." }
Cause: The audio URL is not publicly accessible, has expired, or returned non-audio content.
Solution:
// Verify URL is accessible
const response = await fetch(audioUrl, { method: 'HEAD' });
console.log('Content-Type:', response.headers.get('content-type'));
console.log('Status:', response.status);
// Content-Type should be audio/* or video/*
// For private files, upload directly
const transcript = await client.transcripts.transcribe({
audio: './local-file.mp3', // SDK handles upload
});
{ "status": "error", "error": "Audio file could not be processed" }
Cause: Corrupted file, unsupported codec, file too short (<200ms), or audio is entirely silent.
Solution:
# Check file with ffprobe
ffprobe -v quiet -print_format json -show_format -show_streams input.mp3
# Convert to a known-good format
ffmpeg -i input.unknown -ar 16000 -ac 1 -f wav output.wav
Error: Rate limit exceeded
Status: 429
Header: Retry-After: 30
Cause: Too many concurrent requests. Free tier: 5 streams/min. Paid: 100 streams/min (auto-scales).
Solution:
import { AssemblyAI } from 'assemblyai';
async function transcribeWithBackoff(audioUrl: string, retries = 3) {
const client = new AssemblyAI({ apiKey: process.env.ASSEMBLYAI_API_KEY! });
for (let attempt = 0; attempt <= retries; attempt++) {
try {
return await client.transcripts.transcribe({ audio: audioUrl });
} catch (err: any) {
if (err.status !== 429 || attempt === retries) throw err;
const delay = Math.pow(2, attempt) * 1000 + Math.random() * 500;
console.warn(`Rate limited. Retrying in ${delay.toFixed(0)}ms...`);
await new Promise(r => setTimeout(r, delay));
}
}
}
WebSocket error: 4001 Not Authorized
WebSocket error: 4008 Session limit reached
WebSocket error: 4100 Endpoint not found
| Code | Meaning | Solution |
|---|---|---|
4001 |
Bad API key or expired token | Refresh token via client.streaming.createTemporaryToken() |
4008 |
Max concurrent streams reached | Wait for existing streams to close |
4100 |
Wrong WebSocket URL | Use wss://api.assemblyai.com/v2/realtime/ws |
4010 |
Audio too short/no speech | Ensure microphone is capturing audio |
{ "error": "Transcript not found" }
{ "error": "Input text exceeds maximum length" }
Cause: Invalid transcript_ids or total audio exceeds 100-hour limit.
Solution:
// Verify transcript exists before LeMUR call
const transcript = await client.transcripts.get(transcriptId);
if (transcript.status !== 'completed') {
throw new Error(`Transcript ${transcriptId} status: ${transcript.status}`);
}
// For large inputs, chunk transcript_ids
const chunks = [];
for (let i = 0; i < transcriptIds.length; i += 10) {
chunks.push(transcriptIds.slice(i, i + 10));
}
for (const chunk of chunks) {
const { response } = await client.lemur.task({
transcript_ids: chunk,
prompt: 'Summarize key points.',
});
}
{ "status": "error", "error": "Language not supported" }
Cause: Specified language_code is not available for the selected model.
Solution:
// Use automatic language detection (recommended)
const transcript = await client.transcripts.transcribe({
audio: audioUrl,
language_detection: true, // Auto-detect from 99+ languages
});
console.log('Detected language:', transcript.language_code);
Symptom: Custom terms are still transcribed incorrectly despite word_boost.
Solution:
const transcript = await client.transcripts.transcribe({
audio: audioUrl,
word_boost: ['LeMUR', 'AssemblyAI', 'Nova-3'], // Max 1000 terms
boost_param: 'high', // 'low' | 'default' | 'high'
speech_model: 'best', // Word boost works with Best model tier
});
# Check API status
curl -s https://status.assemblyai.com/api/v2/status.json | jq '.status.description'
# Test API connectivity
curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: $ASSEMBLYAI_API_KEY" \
https://api.assemblyai.com/v2/transcript
# Check installed SDK version
npm list assemblyai
# Verify env variable
node -e "console.log(process.env.ASSEMBLYAI_API_KEY ? 'SET' : 'NOT SET')"
| Error | HTTP Code | Retryable | Action |
|---|---|---|---|
| Auth error | 401 | No | Fix API key |
| Not found | 404 | No | Check transcript ID |
| Rate limit | 429 | Yes | Exponential backoff |
| Server error | 500-503 | Yes | Retry after delay |
| Download error | N/A | Maybe | Check audio URL accessibility |
For comprehensive debugging, see assemblyai-debug-bundle.