Skip to main content
Learn how to properly handle errors, implement retry logic, and troubleshoot common issues when using the VoiceDub API.

Error Response Format

All API errors return a consistent JSON structure: Error Response:
{
  "code": "error_code_here",
  "message": "Human-readable error description"
}

HTTP Status Codes

400 Bad Request

Invalid request parameters or malformed data. 400 Examples:
{
  "code": "invalid_arguments",
  "message": "Invalid request parameters or body",
  "errors": {
    "params": "...",
    "query": "...",
    "body": "..."
  }
}

{
  "code": "voice_not_found",
  "message": "Voice not found or not accessible"
}
Common causes:
  • Invalid UUID format for voice or dub IDs
  • Missing required parameters
  • Invalid parameter values (e.g., pitch shift outside -24 to +24 range)
  • Passing a voiceId for a voice that does not exist or is not accessible

401 Unauthorized

Authentication failed or API key issues. 401 Examples:
{
  "code": "unauthorized",
  "message": "You are not authorized to perform this action"
}
Common causes:
  • Missing Authorization header
  • Incorrect API key format (should be Api-Key YOUR_KEY)
  • Deleted or expired API key

403 Forbidden

Valid request but insufficient permissions or credits. 403 Examples:
{
  "code": "not_enough_credits",
  "message": "Looks like you don't have enough credits! Purchase more at https://voicedub.ai/developer/billing"
}
Common causes:
  • Insufficient API credits for operation

404 Not Found

Resource doesn’t exist or you don’t have access. 404 Examples:
{
  "code": "not_found",
  "message": "Dub not found"
}

{
  "code": "not_found", 
  "message": "Voice not found"
}
Common causes:
  • Invalid resource ID

429 Rate Limited

Too many requests in a short time period. 429 Example:
{
  "code": "rate_limit_exceeded",
  "message": "Rate limit exceeded. Please wait before making more requests."
}

500 Internal Server Error

Server-side error occurred. 500 Example:
{
  "code": "internal_error",
  "message": "An internal server error occurred. Please try again later."
}
When this happens:
  • Temporary server issues
  • Unexpected system errors

Retry Logic

Implement exponential backoff for transient errors:
async function apiRequestWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch(url, options);
      
      // Don't retry client errors (4xx except 429)
      if (response.status >= 400 && response.status < 500 && response.status !== 429) {
        const error = await response.json();
        throw new Error(`${error.code}: ${error.message}`);
      }
      
      // Retry server errors (5xx) and rate limits (429)
      if (response.status >= 500 || response.status === 429) {
        if (attempt === maxRetries) {
          throw new Error(`Request failed after ${maxRetries + 1} attempts`);
        }
        
        // Exponential backoff with jitter: 1s-2s, 2s-3s, 4s-5s
        const baseDelay = Math.pow(2, attempt) * 1000;
        const jitter = Math.random() * 1000; // 0-1 second jitter
        const delay = baseDelay + jitter;
        console.log(`Attempt ${attempt + 1} failed, retrying in ${delay.toFixed(0)}ms...`);
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }
      
      // Success
      return await response.json();
      
    } catch (error) {
      if (attempt === maxRetries) throw error;
      
      // Exponential backoff with jitter for network errors
      const baseDelay = Math.pow(2, attempt) * 1000;
      const jitter = Math.random() * 1000; // 0-1 second jitter
      const delay = baseDelay + jitter;
      console.log(`Network error, retrying in ${delay.toFixed(0)}ms...`);
      await new Promise(resolve => setTimeout(resolve, delay));
    }
  }
}

// Usage
try {
  const data = await apiRequestWithRetry('https://api.voicedub.ai/v1/me', {
    headers: { 'Authorization': `Api-Key ${apiKey}` }
  });
  console.log('Success:', data);
} catch (error) {
  console.error('Failed after retries:', error.message);
}

Status Polling Best Practices

When polling for job completion, follow these guidelines:

Polling Intervals

Never poll faster than once every 3 seconds to avoid rate limiting.
async function pollDubStatus(dubId, maxWaitTime = 600000) { // 10 minutes max
  const startTime = Date.now();
  
  while (Date.now() - startTime < maxWaitTime) {
    const response = await fetch(`https://api.voicedub.ai/v1/me/dubs/${dubId}`, {
      headers: { 'Authorization': `Api-Key ${apiKey}` }
    });
    
    if (!response.ok) {
      throw new Error(`Poll failed: ${response.status}`);
    }
    
    const dub = await response.json();
    
    if (dub.status === 'done') {
      return dub; // Success!
    }
    
    if (dub.status === 'error') {
      throw new Error(`Dub failed: ${dub.errorMessage}`);
    }
    
    // Wait 3 seconds before next poll
    await new Promise(resolve => setTimeout(resolve, 3000));
  }
  
  throw new Error('Polling timeout - job did not complete in time');
}

Common Error Scenarios

Scenario 1: Insufficient Credits

{
  "code": "not_enough_credits",
  "message": "Looks like you don't have enough credits! Purchase more at https://voicedub.ai/developer/billing"
}
  1. Check current credit balance with GET /v1/me
  2. Purchase more credits or enable auto top-up
  3. Retry the request once credits are available
  • Monitor credit balance regularly
  • Set up auto top-up with appropriate thresholds
  • Check requiredCredits after preprocessing before generation
  • Implement credit balance checks in your application

Scenario 2: Processing Failures

{
  "status": "error",
  "errorCode": "processing_failed",
  "errorMessage": "Audio processing failed - invalid format or corrupted file"
}
  1. Check audio file format and quality
  2. Try a different audio file or format
  3. Ensure file is not corrupted
  4. Verify file size is under 50MB
  5. Check if audio contains detectable vocals
  • Use high-quality source audio (192kbps+ MP3 or lossless)
  • Test with shorter clips first
  • Validate file format before upload
  • Use supported formats: MP3, WAV, M4A, FLAC, OGG

Scenario 3: Rate Limiting

{
  "code": "rate_limit_exceeded",
  "message": "Rate limit exceeded. Please wait before making more requests."
}
  1. Implement exponential backoff
  2. Wait before retrying (start with 1 second)
  3. Reduce request frequency
  • Implement request queuing in your application
  • Don’t poll faster than once every 3 seconds
  • Cache responses when appropriate

Error Handling Checklist

✅ Implement proper HTTP status code handling
✅ Parse error responses for specific error codes
✅ Implement exponential backoff for retries
✅ Set appropriate timeouts for long-running operations
✅ Don’t retry 4xx errors (except 429)
✅ Log errors for debugging and monitoring
✅ Provide meaningful error messages to users
✅ Monitor credit balance and handle insufficient credits gracefully

Debugging Tips

Enable Request Logging

Log all API requests and responses for debugging:
const apiCall = async (url, options) => {
  console.log('API Request:', { url, options });
  
  const response = await fetch(url, options);
  const data = await response.json();
  
  console.log('API Response:', { 
    status: response.status, 
    data 
  });
  
  return { response, data };
};

Common Debugging Steps

  1. Verify API key format: Should be Api-Key YOUR_API_KEY
  2. Check request payload: Ensure JSON is valid and complete
  3. Validate UUIDs: Voice and dub IDs must be valid UUID format
  4. Test with cURL: Isolate issues by testing with cURL first
  5. Check network connectivity: Ensure you can reach api.voicedub.ai

Getting Help

When contacting support, include:
  • Dub/Voice ID
  • Complete error response with code and message
  • Steps to reproduce the issue
  • Audio file details (format, size, duration)
  • Timestamp when the error occurred
Need help debugging an issue? Join our Discord community or email [email protected] with the details above.