Veedeo API V3 Error Reference
Complete Error Code Reference Last Updated: January 17, 2025
Table of Contents
- Error Format
- HTTP Status Codes
- Error Categories
- Authentication Errors
- Validation Errors
- Media Processing Errors
- Resource Errors
- System Errors
- Rate Limiting Errors
- Error Handling Best Practices
Error Format
All API errors follow a consistent JSON format:
{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error description",
"details": [
{
"field": "path.to.field",
"issue": "Specific validation issue",
"provided_value": "actual_value_received"
}
],
"request_id": "req_xyz123",
"documentation_url": "https://docs.veedeo.dev/errors/ERROR_CODE",
"suggested_action": "Recommended next steps",
"retry_possible": true,
"retry_after_seconds": 300
}
}
Error Object Fields
Field | Type | Description |
---|---|---|
code | string | Machine-readable error identifier |
message | string | Human-readable error description |
details | array | Specific validation or field errors |
request_id | string | Unique request identifier for debugging |
documentation_url | string | Link to detailed error documentation |
suggested_action | string | Recommended remediation steps |
retry_possible | boolean | Whether the request can be retried |
retry_after_seconds | number | Suggested wait time before retry |
HTTP Status Codes
Status Code | Meaning | When Used |
---|---|---|
200 | OK | Successful GET/POST operations |
201 | Created | Successful resource creation |
400 | Bad Request | Invalid request format or data |
401 | Unauthorized | Missing or invalid authentication |
403 | Forbidden | Valid auth but insufficient permissions |
404 | Not Found | Resource doesn't exist |
409 | Conflict | Resource conflict (duplicate request_id) |
422 | Unprocessable Entity | Valid format but business logic error |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Server-side error |
502 | Bad Gateway | Upstream service error |
503 | Service Unavailable | Temporary service outage |
504 | Gateway Timeout | Request timeout |
Error Categories
Quick Reference
Category | Code Prefix | Retry Possible | Common Causes |
---|---|---|---|
Authentication | AUTH_ | No | Invalid API key, expired token |
Validation | VALIDATION_ | No | Invalid request format, missing fields |
Media | MEDIA_ | Sometimes | Download failures, format issues |
Resource | RESOURCE_ | No | Insufficient credits, quota exceeded |
System | SYSTEM_ | Yes | Server errors, temporary outages |
Rate Limiting | RATE_ | Yes | Too many requests |
Authentication Errors
AUTH_MISSING_TOKEN
HTTP Status: 401 Unauthorized
Description: No authentication token provided
{
"error": {
"code": "AUTH_MISSING_TOKEN",
"message": "Authentication token is required",
"suggested_action": "Include 'Authorization: Bearer your_api_key' header",
"documentation_url": "https://docs.veedeo.dev/errors/AUTH_MISSING_TOKEN",
"retry_possible": false
}
}
Solutions:
- Include
Authorization: Bearer your_api_key
header - Verify header name is correct (case-sensitive)
AUTH_INVALID_TOKEN
HTTP Status: 401 Unauthorized
Description: Invalid or malformed API key
{
"error": {
"code": "AUTH_INVALID_TOKEN",
"message": "Invalid authentication token format",
"details": [
{
"field": "authorization_header",
"issue": "Token does not match expected format",
"provided_value": "Bearer invalid_key_format"
}
],
"suggested_action": "Verify API key format and ensure it's active",
"retry_possible": false
}
}
Solutions:
- Check API key format in dashboard
- Ensure key hasn't been revoked
- Verify no extra spaces in header
AUTH_TOKEN_EXPIRED
HTTP Status: 401 Unauthorized
Description: API key has expired
{
"error": {
"code": "AUTH_TOKEN_EXPIRED",
"message": "Authentication token has expired",
"details": [
{
"field": "api_key",
"issue": "Token expired on 2025-01-15T00:00:00Z",
"expired_at": "2025-01-15T00:00:00Z"
}
],
"suggested_action": "Generate a new API key in the dashboard",
"retry_possible": false
}
}
Solutions:
- Generate new API key
- Update application configuration
- Implement key rotation strategy
AUTH_INSUFFICIENT_PERMISSIONS
HTTP Status: 403 Forbidden
Description: API key lacks required permissions
{
"error": {
"code": "AUTH_INSUFFICIENT_PERMISSIONS",
"message": "API key does not have permission for this operation",
"details": [
{
"required_permission": "renders:create",
"current_permissions": ["renders:read"]
}
],
"suggested_action": "Upgrade account or request additional permissions",
"retry_possible": false
}
}
Solutions:
- Upgrade account tier
- Request additional permissions
- Use different API key with proper permissions
Validation Errors
VALIDATION_MISSING_FIELD
HTTP Status: 400 Bad Request
Description: Required field is missing
{
"error": {
"code": "VALIDATION_MISSING_FIELD",
"message": "Required field is missing",
"details": [
{
"field": "input.timeline",
"issue": "Field is required but not provided"
},
{
"field": "input.output.resolution",
"issue": "Field is required but not provided"
}
],
"suggested_action": "Include all required fields in request body",
"retry_possible": false
}
}
Solutions:
- Review API specification for required fields
- Validate request payload before sending
VALIDATION_INVALID_FORMAT
HTTP Status: 400 Bad Request
Description: Field value doesn't match expected format
{
"error": {
"code": "VALIDATION_INVALID_FORMAT",
"message": "Field value format is invalid",
"details": [
{
"field": "input.timeline.duration_ms",
"issue": "Must be a positive integer",
"provided_value": -5000
},
{
"field": "input.output.resolution.width",
"issue": "Must be between 480 and 7680",
"provided_value": 100
}
],
"suggested_action": "Correct field values according to validation rules",
"retry_possible": false
}
}
Solutions:
- Check field value constraints
- Validate data types
- Ensure values are within acceptable ranges
VALIDATION_INVALID_URL
HTTP Status: 422 Unprocessable Entity
Description: Media URL is invalid or inaccessible
{
"error": {
"code": "VALIDATION_INVALID_URL",
"message": "Media URL is invalid or inaccessible",
"details": [
{
"field": "input.timeline.tracks[0].clips[0].media_url",
"issue": "URL returned 404 Not Found",
"provided_value": "https://example.com/missing-image.jpg"
}
],
"suggested_action": "Verify media URLs are publicly accessible",
"retry_possible": true,
"retry_after_seconds": 60
}
}
Solutions:
- Test URLs in browser
- Ensure files are publicly accessible
- Check for authentication requirements on media URLs
VALIDATION_DUPLICATE_REQUEST_ID
HTTP Status: 409 Conflict
Description: Request ID has already been used
{
"error": {
"code": "VALIDATION_DUPLICATE_REQUEST_ID",
"message": "Request ID has already been used",
"details": [
{
"field": "request_id",
"issue": "Request ID already exists",
"provided_value": "req_duplicate_123",
"original_task_id": "tsk_abc123def456"
}
],
"suggested_action": "Use a unique request_id or omit to auto-generate",
"retry_possible": false
}
}
Solutions:
- Generate new unique request ID
- Omit request_id to auto-generate
- Check if original task meets your needs
Media Processing Errors
MEDIA_DOWNLOAD_FAILED
HTTP Status: 422 Unprocessable Entity
Description: Unable to download media file
{
"error": {
"code": "MEDIA_DOWNLOAD_FAILED",
"message": "Failed to download media file",
"details": [
{
"field": "media_url",
"issue": "Download failed with HTTP 500",
"provided_value": "https://example.com/temporary-error.jpg",
"http_status": 500,
"error_message": "Internal Server Error"
}
],
"suggested_action": "Verify media URL and try again",
"retry_possible": true,
"retry_after_seconds": 300
}
}
Solutions:
- Verify media URL accessibility
- Check server status of media host
- Retry after suggested delay
- Use alternative media URLs
MEDIA_FORMAT_UNSUPPORTED
HTTP Status: 422 Unprocessable Entity
Description: Media file format is not supported
{
"error": {
"code": "MEDIA_FORMAT_UNSUPPORTED",
"message": "Media format is not supported",
"details": [
{
"field": "media_url",
"issue": "Format 'webp' is not supported for video clips",
"provided_value": "https://example.com/image.webp",
"detected_format": "webp",
"supported_formats": ["jpg", "jpeg", "png", "gif"]
}
],
"suggested_action": "Convert media to supported format",
"retry_possible": false
}
}
Solutions:
- Convert media to supported format
- Use different media file
- Check format requirements in documentation
MEDIA_FILE_TOO_LARGE
HTTP Status: 422 Unprocessable Entity
Description: Media file exceeds size limit
{
"error": {
"code": "MEDIA_FILE_TOO_LARGE",
"message": "Media file exceeds maximum size limit",
"details": [
{
"field": "media_url",
"issue": "File size exceeds 100MB limit",
"provided_value": "https://example.com/large-image.jpg",
"file_size_bytes": 157286400,
"max_size_bytes": 104857600
}
],
"suggested_action": "Reduce file size or use smaller media",
"retry_possible": false
}
}
Solutions:
- Compress media file
- Reduce image resolution
- Use different media file
MEDIA_CORRUPTED
HTTP Status: 422 Unprocessable Entity
Description: Media file is corrupted or unreadable
{
"error": {
"code": "MEDIA_CORRUPTED",
"message": "Media file is corrupted or unreadable",
"details": [
{
"field": "media_url",
"issue": "Unable to decode image data",
"provided_value": "https://example.com/corrupted.jpg"
}
],
"suggested_action": "Replace with valid media file",
"retry_possible": false
}
}
Solutions:
- Re-upload media file
- Verify file integrity
- Use different media file
Resource Errors
RESOURCE_INSUFFICIENT_CREDITS
HTTP Status: 402 Payment Required
Description: Account has insufficient credits
{
"error": {
"code": "RESOURCE_INSUFFICIENT_CREDITS",
"message": "Insufficient credits to process request",
"details": [
{
"field": "account_credits",
"issue": "Required 5 credits, available 2 credits",
"required_credits": 5,
"available_credits": 2,
"estimated_cost": 5
}
],
"suggested_action": "Add credits to account or upgrade plan",
"retry_possible": false
}
}
Solutions:
- Purchase additional credits
- Upgrade account plan
- Reduce video complexity
RESOURCE_QUOTA_EXCEEDED
HTTP Status: 429 Too Many Requests
Description: Monthly quota exceeded
{
"error": {
"code": "RESOURCE_QUOTA_EXCEEDED",
"message": "Monthly rendering quota exceeded",
"details": [
{
"field": "monthly_quota",
"issue": "Quota limit reached",
"quota_limit": 100,
"quota_used": 100,
"quota_resets_at": "2025-02-01T00:00:00Z"
}
],
"suggested_action": "Upgrade plan or wait for quota reset",
"retry_possible": false
}
}
Solutions:
- Upgrade to higher plan
- Wait for quota reset
- Optimize render frequency
RESOURCE_CONCURRENT_LIMIT
HTTP Status: 429 Too Many Requests
Description: Concurrent render limit exceeded
{
"error": {
"code": "RESOURCE_CONCURRENT_LIMIT",
"message": "Maximum concurrent renders exceeded",
"details": [
{
"field": "concurrent_renders",
"issue": "Limit reached",
"current_renders": 5,
"max_concurrent": 5
}
],
"suggested_action": "Wait for current renders to complete or upgrade plan",
"retry_possible": true,
"retry_after_seconds": 60
}
}
Solutions:
- Wait for current renders to complete
- Upgrade plan for higher limits
- Implement queue management
System Errors
SYSTEM_INTERNAL_ERROR
HTTP Status: 500 Internal Server Error
Description: Unexpected server error
{
"error": {
"code": "SYSTEM_INTERNAL_ERROR",
"message": "An internal server error occurred",
"request_id": "req_xyz123",
"suggested_action": "Retry request or contact support if problem persists",
"retry_possible": true,
"retry_after_seconds": 30
}
}
Solutions:
- Retry request after delay
- Contact support with request_id
- Check status page for known issues
SYSTEM_SERVICE_UNAVAILABLE
HTTP Status: 503 Service Unavailable
Description: Service temporarily unavailable
{
"error": {
"code": "SYSTEM_SERVICE_UNAVAILABLE",
"message": "Rendering service is temporarily unavailable",
"details": [
{
"field": "service_status",
"issue": "Scheduled maintenance in progress",
"maintenance_end": "2025-01-17T12:00:00Z"
}
],
"suggested_action": "Retry after maintenance window",
"retry_possible": true,
"retry_after_seconds": 1800
}
}
Solutions:
- Wait for maintenance completion
- Check status page
- Retry after suggested delay
SYSTEM_TIMEOUT
HTTP Status: 504 Gateway Timeout
Description: Request processing timed out
{
"error": {
"code": "SYSTEM_TIMEOUT",
"message": "Request processing timed out",
"details": [
{
"field": "processing_time",
"issue": "Exceeded maximum processing time",
"timeout_seconds": 3600
}
],
"suggested_action": "Reduce video complexity or contact support",
"retry_possible": true,
"retry_after_seconds": 300
}
}
Solutions:
- Reduce video length or complexity
- Optimize media file sizes
- Contact support for complex renders
Rate Limiting Errors
RATE_LIMIT_EXCEEDED
HTTP Status: 429 Too Many Requests
Description: API rate limit exceeded
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "API rate limit exceeded",
"details": [
{
"field": "request_rate",
"issue": "Exceeded 100 requests per minute",
"limit": 100,
"window_seconds": 60,
"reset_time": "2025-01-17T10:01:00Z"
}
],
"suggested_action": "Wait before making additional requests",
"retry_possible": true,
"retry_after_seconds": 60
}
}
Solutions:
- Implement exponential backoff
- Reduce request frequency
- Upgrade plan for higher limits
RATE_BURST_LIMIT_EXCEEDED
HTTP Status: 429 Too Many Requests
Description: Burst rate limit exceeded
{
"error": {
"code": "RATE_BURST_LIMIT_EXCEEDED",
"message": "Burst rate limit exceeded",
"details": [
{
"field": "burst_rate",
"issue": "Exceeded 10 requests in 10 seconds",
"burst_limit": 10,
"window_seconds": 10
}
],
"suggested_action": "Slow down request rate",
"retry_possible": true,
"retry_after_seconds": 10
}
}
Solutions:
- Add delays between requests
- Implement request queuing
- Distribute requests over time
Error Handling Best Practices
1. Comprehensive Error Handling
async function handleApiRequest(requestData) {
try {
const response = await veedeoClient.createRender(requestData);
return response;
} catch (error) {
return handleVeedeoError(error);
}
}
function handleVeedeoError(error) {
const { code, message, retry_possible, retry_after_seconds } = error.error;
switch (code) {
case 'AUTH_INVALID_TOKEN':
// Refresh token or prompt user to re-authenticate
return refreshAuthToken();
case 'VALIDATION_MISSING_FIELD':
// Fix validation errors and retry
return fixValidationErrors(error.error.details);
case 'MEDIA_DOWNLOAD_FAILED':
if (retry_possible) {
return scheduleRetry(retry_after_seconds);
}
break;
case 'RESOURCE_INSUFFICIENT_CREDITS':
// Prompt user to add credits
return promptForCredits();
case 'RATE_LIMIT_EXCEEDED':
// Implement exponential backoff
return scheduleRetryWithBackoff(retry_after_seconds);
case 'SYSTEM_INTERNAL_ERROR':
// Log for debugging and retry
console.error('System error:', error);
return scheduleRetry(retry_after_seconds);
default:
// Handle unknown errors
console.error('Unknown error:', error);
throw error;
}
}
2. Retry Logic Implementation
class RetryHandler {
constructor(maxRetries = 3, baseDelay = 1000) {
this.maxRetries = maxRetries;
this.baseDelay = baseDelay;
}
async executeWithRetry(operation, isRetryable = this.defaultRetryable) {
let lastError;
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
try {
return await operation();
} catch (error) {
lastError = error;
if (attempt === this.maxRetries || !isRetryable(error)) {
throw error;
}
const delay = this.calculateDelay(attempt, error);
await this.sleep(delay);
}
}
throw lastError;
}
defaultRetryable(error) {
const retryableCodes = [
'MEDIA_DOWNLOAD_FAILED',
'SYSTEM_INTERNAL_ERROR',
'SYSTEM_SERVICE_UNAVAILABLE',
'SYSTEM_TIMEOUT',
'RATE_LIMIT_EXCEEDED'
];
return error.error?.retry_possible &&
retryableCodes.includes(error.error?.code);
}
calculateDelay(attempt, error) {
// Use suggested delay if provided
if (error.error?.retry_after_seconds) {
return error.error.retry_after_seconds * 1000;
}
// Exponential backoff
return this.baseDelay * Math.pow(2, attempt);
}
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
// Usage
const retryHandler = new RetryHandler();
await retryHandler.executeWithRetry(async () => {
return await veedeoClient.createRender(requestData);
});
3. Error Logging and Monitoring
class ErrorLogger {
constructor() {
this.errorCounts = new Map();
}
logError(error, context = {}) {
const errorData = {
timestamp: '2025-01-17T10:00:00.000Z',
error_code: error.error?.code,
error_message: error.error?.message,
request_id: error.error?.request_id,
http_status: error.statusCode,
context
};
// Log to console
console.error('Veedeo API Error:', errorData);
// Track error frequency
const code = error.error?.code || 'UNKNOWN';
this.errorCounts.set(code, (this.errorCounts.get(code) || 0) + 1);
// Send to monitoring service
this.sendToMonitoring(errorData);
}
sendToMonitoring(errorData) {
// Send to your monitoring service (DataDog, New Relic, etc.)
// monitoring.track('veedeo_api_error', errorData);
}
getErrorStats() {
return Object.fromEntries(this.errorCounts);
}
}
const errorLogger = new ErrorLogger();
// Use in error handling
catch (error) {
errorLogger.logError(error, {
user_id: currentUser.id,
operation: 'create_render',
timeline_duration: requestData.input.timeline.duration_ms
});
throw error;
}
4. User-Friendly Error Messages
function getUserFriendlyMessage(error) {
const { code, message } = error.error;
const userMessages = {
'AUTH_INVALID_TOKEN': 'Please check your API credentials and try again.',
'VALIDATION_MISSING_FIELD': 'Some required information is missing. Please check your request.',
'MEDIA_DOWNLOAD_FAILED': 'Unable to access one or more media files. Please verify your URLs.',
'RESOURCE_INSUFFICIENT_CREDITS': 'You don\'t have enough credits. Please add credits to continue.',
'RATE_LIMIT_EXCEEDED': 'Too many requests. Please wait a moment and try again.',
'SYSTEM_INTERNAL_ERROR': 'A temporary server error occurred. Please try again in a few moments.'
};
return userMessages[code] || 'An unexpected error occurred. Please try again.';
}
// Usage in UI
try {
await createRender(data);
showSuccess('Video render started successfully!');
} catch (error) {
const userMessage = getUserFriendlyMessage(error);
showError(userMessage);
}
For additional error troubleshooting, contact api-support@veedeo.dev with the request_id from the error response.