deepgram-common-errors

SKILL.md

Deepgram Common Errors

Overview

Comprehensive guide to diagnosing and fixing common Deepgram integration errors.

Quick Diagnostic

# Test API connectivity
curl -X POST 'https://api.deepgram.com/v1/listen?model=nova-2' \
  -H "Authorization: Token $DEEPGRAM_API_KEY" \
  -H "Content-Type: audio/wav" \
  --data-binary @test.wav

Common Errors

Authentication Errors

401 Unauthorized

{"err_code": "INVALID_AUTH", "err_msg": "Invalid credentials"}

Causes:

  • Missing or invalid API key
  • Expired API key
  • Incorrect Authorization header format

Solutions:

# Check API key is set
echo $DEEPGRAM_API_KEY

# Verify API key format (should start with valid prefix)
# Test with curl
curl -X GET 'https://api.deepgram.com/v1/projects' \
  -H "Authorization: Token $DEEPGRAM_API_KEY"

403 Forbidden

{"err_code": "ACCESS_DENIED", "err_msg": "Access denied"}

Causes:

  • API key lacks required permissions
  • Feature not enabled on account
  • IP restriction blocking request

Solutions:

  • Check API key permissions in Console
  • Verify account tier supports requested feature
  • Check IP allowlist settings

Audio Processing Errors

400 Bad Request - Invalid Audio

{"err_code": "BAD_REQUEST", "err_msg": "Audio could not be processed"}

Causes:

  • Corrupted audio file
  • Unsupported audio format
  • Empty or silent audio
  • Wrong Content-Type header

Solutions:

// Validate audio before sending
import { createClient } from '@deepgram/sdk';
import { readFileSync, statSync } from 'fs';

function validateAudioFile(filePath: string): boolean {
  const stats = statSync(filePath);

  // Check file size (minimum 100 bytes, maximum 2GB)
  if (stats.size < 100 || stats.size > 2 * 1024 * 1024 * 1024) {
    console.error('Invalid file size');
    return false;
  }

  // Check file header for valid audio format
  const buffer = readFileSync(filePath, { length: 12 });
  const header = buffer.toString('hex', 0, 4);

  const validHeaders = {
    '52494646': 'WAV',   // RIFF
    'fff3': 'MP3',       // MP3
    'fff2': 'MP3',
    'fffb': 'MP3',
    '664c6143': 'FLAC',  // fLaC
    '4f676753': 'OGG',   // OggS
  };

  return Object.keys(validHeaders).some(h => header.startsWith(h));
}

413 Payload Too Large

{"err_code": "PAYLOAD_TOO_LARGE", "err_msg": "Audio file exceeds size limit"}

Solutions:

// Split large files
import { exec } from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(exec);

async function splitAudio(inputPath: string, chunkDuration: number = 300) {
  const outputPattern = inputPath.replace('.wav', '_chunk_%03d.wav');

  await execAsync(
    `ffmpeg -i ${inputPath} -f segment -segment_time ${chunkDuration} ` +
    `-c copy ${outputPattern}`
  );
}

Rate Limiting Errors

429 Too Many Requests

{"err_code": "RATE_LIMIT_EXCEEDED", "err_msg": "Rate limit exceeded"}

Solutions:

// Implement rate limiting
class RateLimiter {
  private queue: Array<() => Promise<void>> = [];
  private processing = false;
  private lastRequest = 0;
  private minInterval = 100; // ms between requests

  async add<T>(fn: () => Promise<T>): Promise<T> {
    return new Promise((resolve, reject) => {
      this.queue.push(async () => {
        const now = Date.now();
        const elapsed = now - this.lastRequest;

        if (elapsed < this.minInterval) {
          await new Promise(r => setTimeout(r, this.minInterval - elapsed));
        }

        try {
          this.lastRequest = Date.now();
          resolve(await fn());
        } catch (error) {
          reject(error);
        }
      });

      this.process();
    });
  }

  private async process() {
    if (this.processing) return;
    this.processing = true;

    while (this.queue.length > 0) {
      const fn = this.queue.shift()!;
      await fn();
    }

    this.processing = false;
  }
}

WebSocket Errors

Connection Refused

Error: WebSocket connection failed

Causes:

  • Firewall blocking WebSocket
  • Incorrect URL
  • Network issues

Solutions:

// Test WebSocket connectivity
async function testWebSocketConnection() {
  const ws = new WebSocket('wss://api.deepgram.com/v1/listen', {
    headers: {
      Authorization: `Token ${process.env.DEEPGRAM_API_KEY}`,
    },
  });

  return new Promise((resolve, reject) => {
    ws.onopen = () => {
      console.log('WebSocket connected');
      ws.close();
      resolve(true);
    };

    ws.onerror = (error) => {
      console.error('WebSocket error:', error);
      reject(error);
    };

    setTimeout(() => reject(new Error('Connection timeout')), 10000);
  });
}

Connection Dropped

Error: WebSocket closed unexpectedly

Solutions:

// Implement keep-alive
class DeepgramWebSocket {
  private keepAliveInterval: NodeJS.Timeout | null = null;

  start() {
    // Send keep-alive every 10 seconds
    this.keepAliveInterval = setInterval(() => {
      if (this.connection?.readyState === WebSocket.OPEN) {
        this.connection.send(JSON.stringify({ type: 'KeepAlive' }));
      }
    }, 10000);
  }

  stop() {
    if (this.keepAliveInterval) {
      clearInterval(this.keepAliveInterval);
    }
  }
}

Transcription Quality Issues

Empty or Incorrect Transcripts

Diagnostic Steps:

  1. Check audio sample rate (16kHz recommended)
  2. Verify audio is mono or stereo
  3. Test with known-good audio file
  4. Check language setting matches audio
// Debug transcription
async function debugTranscription(audioPath: string) {
  const client = createClient(process.env.DEEPGRAM_API_KEY!);

  const { result, error } = await client.listen.prerecorded.transcribeFile(
    readFileSync(audioPath),
    {
      model: 'nova-2',
      smart_format: true,
      // Enable all debug features
      alternatives: 3,
      words: true,
      utterances: true,
    }
  );

  if (error) {
    console.error('Error:', error);
    return;
  }

  // Check confidence scores
  const alt = result.results.channels[0].alternatives[0];
  console.log('Confidence:', alt.confidence);
  console.log('Word count:', alt.words?.length);
  console.log('Low confidence words:', alt.words?.filter(w => w.confidence < 0.7));
}

Error Reference Table

HTTP Code Error Code Common Cause Solution
400 BAD_REQUEST Invalid audio format Check audio encoding
401 INVALID_AUTH Missing/invalid API key Verify API key
403 ACCESS_DENIED Permission denied Check account permissions
404 NOT_FOUND Invalid endpoint Check API URL
413 PAYLOAD_TOO_LARGE File too large Split audio file
429 RATE_LIMIT_EXCEEDED Too many requests Implement backoff
500 INTERNAL_ERROR Server error Retry with backoff
503 SERVICE_UNAVAILABLE Service down Check status page

Resources

Next Steps

Proceed to deepgram-debug-bundle for collecting debug evidence.

Weekly Installs
14
GitHub Stars
1.6K
First Seen
Feb 18, 2026
Installed on
codex14
mcpjam13
claude-code13
junie13
windsurf13
zencoder13