API Error Codes and Handling
Complete reference for VocaFuse API error codes and troubleshooting. Explains HTTP status codes, error response formats, and common scenarios. Includes error handling examples in JavaScript and Python.
Error Response Format
All API errors follow a consistent format:
{
  "error": {
    "code": 2003,
    "message": "Invalid field value",
    "details": {
      "field": "voicenote_id",
      "reason": "must be a valid UUID"
    }
  }
}
HTTP Status Codes
| Status | Description | 
|---|---|
| 200 | Success | 
| 201 | Created | 
| 204 | No Content (successful deletion) | 
| 400 | Bad Request - Invalid parameters | 
| 401 | Unauthorized - Invalid API credentials | 
| 403 | Forbidden - Insufficient permissions | 
| 404 | Not Found - Resource doesn't exist | 
| 429 | Rate Limit Exceeded | 
| 500 | Internal Server Error | 
| 503 | Service Unavailable | 
Error Codes
Error codes are organized by category (1xxx = Authentication, 2xxx = Validation, etc.)
Authentication Errors (1xxx)
INVALID_TOKEN (1001)
JWT token is missing or malformed.
{
  "error": {
    "code": 1001,
    "message": "Invalid or malformed token"
  }
}
Solution: Ensure you're passing a valid JWT token from your backend
TOKEN_EXPIRED (1002)
JWT token has expired.
{
  "error": {
    "code": 1002,
    "message": "Token has expired"
  }
}
Solution: Request a new token from your backend token endpoint
Validation Errors (2xxx)
INVALID_REQUEST_FORMAT (2001)
Request body is malformed or not valid JSON.
{
  "error": {
    "code": 2001,
    "message": "Request body is malformed"
  }
}
Solution: Verify your request body is valid JSON
MISSING_REQUIRED_FIELD (2002)
Required field is missing from the request.
{
  "error": {
    "code": 2002,
    "message": "Required field missing",
    "details": {
      "field": "identity"
    }
  }
}
Solution: Check API documentation for required fields
INVALID_FIELD_VALUE (2003)
Field value is invalid.
{
  "error": {
    "code": 2003,
    "message": "Invalid field value",
    "details": {
      "field": "expires_in",
      "value": "invalid",
      "reason": "must be an integer between 60 and 86400"
    }
  }
}
Solution: Verify parameter values match the API specification
FILE_SIZE_EXCEEDED (2004)
Uploaded file exceeds size limit.
{
  "error": {
    "code": 2004,
    "message": "File size exceeds maximum limit",
    "details": {
      "max_size": "25MB",
      "actual_size": "30MB"
    }
  }
}
Solution: Ensure audio files are under 25MB
UNSUPPORTED_AUDIO_FORMAT (2005)
Audio format is not supported.
{
  "error": {
    "code": 2005,
    "message": "Audio format not supported",
    "details": {
      "format": "mp3",
      "supported_formats": ["webm", "wav", "ogg"]
    }
  }
}
Solution: Convert audio to a supported format (webm, wav, or ogg)
RECORDING_TOO_LONG (2006)
Voice note exceeds maximum duration.
{
  "error": {
    "code": 2006,
    "message": "Recording exceeds maximum duration",
    "details": {
      "max_duration": 60,
      "actual_duration": 75
    }
  }
}
Solution: Keep voice notes under 60 seconds
Processing Errors (3xxx)
TRANSCRIPTION_FAILED (3003)
Audio transcription failed.
{
  "error": {
    "code": 3003,
    "message": "Failed to transcribe audio",
    "details": {
      "reason": "Audio quality too low"
    }
  }
}
Solution: Ensure audio quality is sufficient. Try recording in a quieter environment.
AUDIO_PROCESSING_FAILED (3004)
Audio processing failed.
{
  "error": {
    "code": 3004,
    "message": "Failed to process audio file"
  }
}
Solution: Verify the audio file is valid and not corrupted
Rate Limiting (4xxx)
RATE_LIMIT_EXCEEDED (4003)
Too many requests in a given time window.
{
  "error": {
    "code": 4003,
    "message": "Rate limit exceeded",
    "details": {
      "limit": 100,
      "window": "1 minute",
      "retry_after": 45
    }
  }
}
Solution: Implement exponential backoff and retry after the specified time
System Errors (5xxx)
WEBHOOK_ALREADY_EXISTS (5005)
Webhook URL already registered.
{
  "error": {
    "code": 5005,
    "message": "Webhook already exists for this URL",
    "details": {
      "url": "https://example.com/webhook"
    }
  }
}
Solution: Use the existing webhook or delete it first before recreating
INTERNAL_SERVER_ERROR (5001)
An unexpected error occurred on the server.
{
  "error": {
    "code": 5001,
    "message": "Internal server error"
  }
}
Solution: Retry the request. If the error persists, contact support.
SERVICE_UNAVAILABLE (5002)
Service is temporarily unavailable.
{
  "error": {
    "code": 5002,
    "message": "Service temporarily unavailable"
  }
}
Solution: Retry the request after a short delay
Resource Errors (6xxx)
RECORDING_NOT_FOUND (6001)
Voice note doesn't exist or you don't have access.
{
  "error": {
    "code": 6001,
    "message": "Voice note not found",
    "details": {
      "voicenote_id": "rec_invalid123"
    }
  }
}
Solution: Verify the voice note ID is correct
TRANSCRIPTION_NOT_FOUND (6002)
Transcription not available for this voice note.
{
  "error": {
    "code": 6002,
    "message": "Transcription not found",
    "details": {
      "voicenote_id": "rec_123"
    }
  }
}
Solution: Wait for transcription to complete or check if it failed
WEBHOOK_NOT_FOUND (6003)
Webhook doesn't exist.
{
  "error": {
    "code": 6003,
    "message": "Webhook not found",
    "details": {
      "webhook_id": "webhook_123"
    }
  }
}
Solution: Verify the webhook ID is correct
Client-Side Errors
Frontend SDK Error Codes
- JavaScript
 
sdk.addVoiceNote('#record-btn', {
  onError: (error) => {
    switch (error.code) {
      case 'PERMISSION_DENIED':
        // User denied microphone access
        showMessage('Please allow microphone access');
        break;
        
      case 'NOT_SUPPORTED':
        // Browser doesn't support recording
        showMessage('Browser not supported');
        break;
        
      case 'DURATION_EXCEEDED':
        // Recording exceeded max duration
        showMessage('Recording too long (max 60s)');
        break;
        
      case 'NETWORK_ERROR':
        // Upload failed due to network
        showMessage('Network error. Please try again');
        break;
        
      case 'AUTHENTICATION_FAILED':
        // Token expired or invalid
        await refreshToken();
        break;
        
      default:
        showMessage(error.userMessage);
    }
  }
});
Error Object
- TypeScript
 
interface VocaFuseError {
  code: string;           // Error code
  message: string;        // Technical message
  userMessage: string;    // User-friendly message
  details?: object;       // Additional context
  timestamp: number;      // Unix timestamp
}
Error Handling Examples
Python SDK
- Python
 - Node.js
 
from vocafuse import (
    Client,
    VocaFuseError,
    AuthenticationError,
    RateLimitError,
    NotFoundError
)
client = Client(api_key='sk_live_...', api_secret='...')
try:
    voicenote = client.voicenotes.get('rec_123')
    
except AuthenticationError as e:
    print(f'Authentication failed: {e.message}')
    # Error code 1001 or 1002
    # Update credentials or refresh token
    
except NotFoundError as e:
    print(f'Voice note not found: {e.message}')
    # Error code 6001
    # Handle missing resource
    
except RateLimitError as e:
    retry_after = e.retry_after
    print(f'Rate limited. Retry after {retry_after}s')
    # Error code 4003
    # Implement backoff
    time.sleep(retry_after)
    
except VocaFuseError as e:
    print(f'API Error {e.code}: {e.message}')
    # Log and handle generic errors
    
except Exception as e:
    print(f'Unexpected error: {e}')
    # Handle unexpected errors
// Node.js example (when backend SDK is available)
const client = require('@vocafuse/backend-sdk');
try {
  const voicenote = await client.voicenotes.get('rec_123');
  
} catch (error) {
  // Error codes match the Python SDK
  if (error.code === 1001 || error.code === 1002) {
    console.error('Authentication error:', error.message);
    // Update credentials or refresh token
    
  } else if (error.code === 6001) {
    console.error('Voice note not found:', error.message);
    // Handle missing resource
    
  } else if (error.code === 4003) {
    const retryAfter = error.retryAfter;
    console.error(`Rate limited. Retry after ${retryAfter}s`);
    // Implement backoff
    await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
    
  } else {
    console.error(`API Error ${error.code}: ${error.message}`);
    // Log and handle generic errors
  }
}
Retry Logic
- Python
 
import time
from vocafuse import Client, RateLimitError
def get_voicenote_with_retry(voicenote_id, max_retries=3):
    client = Client(api_key='sk_live_...', api_secret='...')
    
    for attempt in range(max_retries):
        try:
            return client.voicenotes.get(voicenote_id)
            
        except RateLimitError as e:
            # Error code 4003
            if attempt < max_retries - 1:
                wait_time = e.retry_after
                print(f'Rate limited. Waiting {wait_time}s...')
                time.sleep(wait_time)
            else:
                raise
                
        except Exception as e:
            if attempt < max_retries - 1:
                wait_time = 2 ** attempt  # Exponential backoff
                print(f'Error: {e}. Retrying in {wait_time}s...')
                time.sleep(wait_time)
            else:
                raise
Best Practices
1. Always Handle Errors
- JavaScript
 
// ❌ Bad - no error handling
const voicenote = await client.voicenotes.get('rec_123');
// ✅ Good - proper error handling
try {
  const voicenote = await client.voicenotes.get('rec_123');
} catch (error) {
  logger.error('Failed to fetch voice note', { 
    error, 
    errorCode: error.code,
    voicenoteId: 'rec_123' 
  });
  throw error;
}
2. Implement Retries
- Python
 
# For transient errors (network, rate limits)
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(
    stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=1, min=2, max=60)
)
def create_voicenote(audio_file):
    return client.voicenotes.create(audio_file)
3. User-Friendly Messages
- JavaScript
 
function getErrorMessage(error) {
  const messages = {
    'PERMISSION_DENIED': 'Please allow microphone access to record',
    'DURATION_EXCEEDED': 'Recording is too long. Maximum is 60 seconds',
    'NETWORK_ERROR': 'Connection lost. Please check your internet',
    'AUTHENTICATION_FAILED': 'Session expired. Please refresh the page'
  };
  
  return messages[error.code] || 'An error occurred. Please try again';
}
4. Log Errors
- Python
 
import logging
logger = logging.getLogger(__name__)
try:
    voicenote = client.voicenotes.get('rec_123')
except VocaFuseError as e:
    logger.error(
        'API error',
        extra={
            'error_code': e.code,
            'error_message': e.message,
            'voicenote_id': 'rec_123',
            'user_id': user.id
        }
    )
Testing Error Handling
- Python
 
import pytest
from vocafuse import Client, NotFoundError, RateLimitError
from unittest.mock import patch
def test_handles_not_found():
    client = Client(api_key='sk_test_...', api_secret='...')
    
    with pytest.raises(NotFoundError) as exc_info:
        client.voicenotes.get('invalid_id')
    
    assert exc_info.value.code == 6001
def test_retry_on_rate_limit():
    client = Client(api_key='sk_test_...', api_secret='...')
    
    # Use mock to simulate rate limit
    with patch.object(client.voicenotes, 'list') as mock:
        mock.side_effect = [
            RateLimitError(code=4003, retry_after=1), 
            {'data': []}
        ]
        
        result = get_voicenote_with_retry('rec_123')
        
        assert mock.call_count == 2
        assert result is not None