Back to site
ProsodyAI Docs
API Reference

Error Handling

API error codes and troubleshooting

Error Handling

The ProsodyAI API uses standard HTTP status codes and returns detailed error information in JSON format.

Error Response Format

{
  "error": {
    "code": "error_code",
    "message": "Human-readable error message",
    "details": {
      // Additional context (optional)
    },
    "request_id": "req_abc123"
  }
}

HTTP Status Codes

StatusDescription
200Success
400Bad Request - Invalid parameters
401Unauthorized - Invalid or missing API key
403Forbidden - Insufficient permissions
404Not Found - Resource doesn't exist
413Payload Too Large - File exceeds limit
415Unsupported Media Type - Invalid audio format
422Unprocessable Entity - Valid format but can't process
429Too Many Requests - Rate limit exceeded
500Internal Server Error
503Service Unavailable - Temporary outage

Common Error Codes

Authentication Errors

unauthorized

{
  "error": {
    "code": "unauthorized",
    "message": "Invalid or missing API key"
  }
}

Solution: Check your API key is correct and included in the Authorization header.

api_key_expired

{
  "error": {
    "code": "api_key_expired",
    "message": "API key has expired",
    "details": {
      "expired_at": "2025-01-01T00:00:00Z"
    }
  }
}

Solution: Generate a new API key in the dashboard.

Validation Errors

validation_error

{
  "error": {
    "code": "validation_error",
    "message": "Invalid request parameters",
    "details": {
      "audio_url": ["Invalid URL format"],
      "vertical": ["Must be one of: contact_center, healthcare, sales, ..."]
    }
  }
}

Solution: Check request parameters match the API specification.

missing_audio

{
  "error": {
    "code": "missing_audio",
    "message": "No audio provided. Include audio, audio_url, or audio_base64"
  }
}

Solution: Provide audio via file upload, URL, or base64 encoding.

Audio Errors

unsupported_audio_format

{
  "error": {
    "code": "unsupported_audio_format",
    "message": "Unsupported audio format: video/mp4",
    "details": {
      "detected_format": "video/mp4",
      "supported_formats": ["audio/wav", "audio/mpeg", "audio/ogg", "audio/webm", "audio/flac"]
    }
  }
}

Solution: Convert audio to a supported format (WAV recommended).

audio_too_short

{
  "error": {
    "code": "audio_too_short",
    "message": "Audio duration too short for analysis",
    "details": {
      "minimum_duration": 0.5,
      "actual_duration": 0.2
    }
  }
}

Solution: Provide audio at least 0.5 seconds long.

audio_too_long

{
  "error": {
    "code": "audio_too_long",
    "message": "Audio duration exceeds maximum for single analysis",
    "details": {
      "maximum_duration": 300,
      "actual_duration": 450
    }
  }
}

Solution: Use streaming API for long audio, or split into segments.

audio_fetch_failed

{
  "error": {
    "code": "audio_fetch_failed",
    "message": "Failed to fetch audio from URL",
    "details": {
      "url": "https://example.com/audio.wav",
      "status": 404
    }
  }
}

Solution: Verify the audio URL is accessible and returns valid audio.

Rate Limiting

rate_limit_exceeded

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded",
    "details": {
      "limit": 1000,
      "window": "1m",
      "retry_after": 45
    }
  }
}

Solution: Wait for retry_after seconds, or upgrade your plan.

Rate limit info is also in response headers:

  • X-RateLimit-Limit: Requests per minute
  • X-RateLimit-Remaining: Remaining requests
  • X-RateLimit-Reset: Reset timestamp

Resource Errors

session_not_found

{
  "error": {
    "code": "session_not_found",
    "message": "Session not found",
    "details": {
      "session_id": "call-12345"
    }
  }
}

Solution: Verify the session ID is correct and hasn't expired.

fine_tune_not_found

{
  "error": {
    "code": "fine_tune_not_found",
    "message": "Fine-tuning job not found",
    "details": {
      "job_id": "ft-abc123"
    }
  }
}

Processing Errors

audio_processing_failed

{
  "error": {
    "code": "audio_processing_failed",
    "message": "Failed to process audio",
    "details": {
      "reason": "Corrupted audio file"
    }
  }
}

Solution: Verify the audio file is valid and not corrupted.

model_unavailable

{
  "error": {
    "code": "model_unavailable",
    "message": "Requested model is temporarily unavailable",
    "details": {
      "model": "ft-model-xyz"
    }
  }
}

Solution: Retry the request, or use a different model.

Error Handling Best Practices

Retry Logic

Implement exponential backoff for transient errors:

async function analyzeWithRetry(request: AnalyzeRequest, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await client.analyze(request);
    } catch (error) {
      if (error instanceof RateLimitError) {
        await sleep(error.retryAfter * 1000);
        continue;
      }
      
      if (error.status >= 500 && attempt < maxRetries - 1) {
        await sleep(Math.pow(2, attempt) * 1000);
        continue;
      }
      
      throw error;
    }
  }
}

Error Logging

Include request_id in logs for debugging:

try {
  const result = await client.analyze({ audio });
} catch (error) {
  console.error('Analysis failed', {
    code: error.code,
    message: error.message,
    requestId: error.requestId,
  });
}

User-Friendly Messages

Map error codes to user-friendly messages:

const errorMessages: Record<string, string> = {
  'unauthorized': 'Please check your API key configuration.',
  'rate_limit_exceeded': 'Too many requests. Please try again in a moment.',
  'unsupported_audio_format': 'Please upload a WAV, MP3, or OGG file.',
  'audio_too_short': 'Audio must be at least half a second long.',
};

function getUserMessage(error: ProsodyError): string {
  return errorMessages[error.code] || 'An unexpected error occurred.';
}