Skip to main content

Error Handling

How to handle errors from the ReelBot Developer API.

Error Response Format

All error responses follow this structure:

{
"success": false,
"message": "Human-readable error description",
"code": "ERROR_CODE",
"details": { }
}
FieldTypeDescription
successbooleanAlways false for errors
messagestringHuman-readable error message
codestringMachine-readable error code
detailsobjectAdditional context (optional)

HTTP Status Codes

StatusMeaningAction
200SuccessProcess response
400Bad RequestFix request parameters
401UnauthorizedCheck API key
402Payment RequiredUpgrade plan or wait for quota reset
403ForbiddenCheck permissions
404Not FoundCheck resource ID
429Too Many RequestsWait and retry
500Internal Server ErrorRetry with backoff
503Service UnavailableRetry later

Error Codes Reference

Authentication Errors

CodeStatusDescriptionSolution
UNAUTHORIZED401Missing or invalid API keyCheck X-API-Key header

Validation Errors

CodeStatusDescriptionSolution
VALIDATION_ERROR400Invalid request parametersCheck message for details
INVALID_JSON400Malformed JSON bodyValidate JSON syntax
INVALID_PROJECT_ID400Invalid project ID formatCheck project ID
INVALID_KEY_ID400Invalid API key ID formatCheck key ID

Resource Errors

CodeStatusDescriptionSolution
NOT_FOUND404Resource doesn't existVerify resource ID
OUTPUT_NOT_FOUND404Video output missingContact support
VIDEO_NOT_READY400Video still processingWait for completed status

Quota & Rate Limit Errors

CodeStatusDescriptionSolution
QUOTA_EXCEEDED402Plan quota exhaustedUpgrade plan or wait
RATE_LIMITED429Too many requestsWait until resetAt
KEY_LIMIT_REACHED409Already have an API keyRevoke existing key first

Server Errors

CodeStatusDescriptionSolution
INTERNAL_ERROR500Unexpected server errorRetry with backoff
SERVICE_UNAVAILABLE503Service temporarily downRetry later
CONFIG_ERROR500Server misconfigurationContact support

Common Validation Errors

Missing Required Fields

{
"success": false,
"message": "videoType is required",
"code": "VALIDATION_ERROR"
}

Common missing fields:

  • videoType
  • topic
  • brollKeys
  • script (for narrated videos)
  • voiceId (for narrated videos without voiceoverKey)

Invalid Enum Values

{
"success": false,
"message": "aspectRatio must be one of: 9:16, 16:9, 1:1",
"code": "VALIDATION_ERROR"
}

Valid values:

  • videoType: "narrated", "cinematic"
  • aspectRatio: "9:16", "16:9", "1:1"
  • scriptDuration: 15, 30, 45, 60
  • captionSize: "small", "medium", "large"
  • tone: "professional", "casual", "humorous", "inspirational", "educational"

Invalid Asset Paths

{
"success": false,
"message": "Invalid b-roll key \"../../../etc/passwd\": Invalid asset path: path traversal detected",
"code": "VALIDATION_ERROR"
}

Valid asset path formats:

users/{your-user-id}/b-roll/filename.mp4
users/{your-user-id}/music/filename.mp3
users/{your-user-id}/voiceovers/filename.mp3
shared/b-roll/filename.mp4
shared/music/filename.mp3

Invalid Trim Settings

{
"success": false,
"message": "Invalid trim settings for users/abc/b-roll/clip.mp4: startTime must be less than endTime",
"code": "VALIDATION_ERROR"
}

Requirements:

  • startTime must be ≥ 0
  • endTime must be > startTime
  • Both must be numbers

Handling Rate Limits

When you receive a 429 response:

{
"success": false,
"message": "Rate limit exceeded. Please try again later.",
"code": "RATE_LIMITED",
"details": {
"resetAt": "2025-01-21T17:00:00.000Z"
}
}

Response Headers

HeaderDescription
Retry-AfterSeconds until rate limit resets
X-RateLimit-RemainingRequests remaining in window
X-RateLimit-ResetISO timestamp when limit resets

Retry Strategy

async function requestWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options);

if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || 60;
console.log(`Rate limited. Waiting ${retryAfter} seconds...`);
await new Promise(r => setTimeout(r, retryAfter * 1000));
continue;
}

return response;
}

throw new Error('Max retries exceeded');
}

Handling Server Errors

For 500 and 503 errors, implement exponential backoff:

async function requestWithBackoff(url, options, maxRetries = 5) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(url, options);

if (response.status >= 500) {
const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s, 8s, 16s
console.log(`Server error. Retrying in ${delay}ms...`);
await new Promise(r => setTimeout(r, delay));
continue;
}

return response;
} catch (error) {
if (i === maxRetries - 1) throw error;
const delay = Math.pow(2, i) * 1000;
await new Promise(r => setTimeout(r, delay));
}
}
}

Best Practices

1. Always Check success

const response = await fetch(url, options);
const data = await response.json();

if (!data.success) {
console.error(`Error: ${data.code} - ${data.message}`);
// Handle error appropriately
}

2. Log Correlation IDs

When contacting support, include the correlationId from successful responses:

const data = await response.json();
console.log(`Request ID: ${data.correlationId}`);

3. Validate Before Sending

Check parameters client-side before making API calls:

function validateRequest(params) {
if (!['narrated', 'cinematic'].includes(params.videoType)) {
throw new Error('Invalid videoType');
}

if (!params.topic || params.topic.length > 500) {
throw new Error('Invalid topic');
}

if (!params.brollKeys || params.brollKeys.length === 0) {
throw new Error('brollKeys required');
}

// ... more validation
}

4. Handle Quota Gracefully

if (data.code === 'QUOTA_EXCEEDED') {
// Notify user
// Queue for later
// Suggest upgrade
}

Getting Help

If you encounter persistent errors:

  1. Check this documentation for the error code
  2. Verify your request matches the examples
  3. Include the correlationId when contacting support
  4. Provide the full error response

Contact: support@reelbot.space