Skip to main content

Examples

Complete, working examples for common use cases.

End-to-End: Generate and Download

Bash / cURL

#!/bin/bash
set -e

API_KEY="rb_live_your_key_here"
BASE_URL="https://reelbot.space/api/v1"

# 1. Generate video
echo "Starting video generation..."
GENERATE_RESPONSE=$(curl -s -X POST "$BASE_URL/video/generate" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"videoType": "narrated",
"topic": "3 Morning Habits for Success",
"script": "Here are three morning habits that successful people swear by. First, wake up early. The quiet morning hours are perfect for focused work. Second, exercise. Even 15 minutes gets your blood flowing. Third, plan your day. Take 5 minutes to prioritize your tasks.",
"voiceId": "matthew",
"brollKeys": [
"users/YOUR_USER_ID/b-roll/morning-sunrise.mp4",
"users/YOUR_USER_ID/b-roll/exercise.mp4",
"users/YOUR_USER_ID/b-roll/planning.mp4"
],
"aspectRatio": "9:16",
"scriptDuration": 30,
"captionSize": "medium",
"tone": "inspirational"
}')

PROJECT_ID=$(echo $GENERATE_RESPONSE | jq -r '.projectId')
echo "Project ID: $PROJECT_ID"

# 2. Poll for completion
echo "Waiting for video to complete..."
while true; do
STATUS_RESPONSE=$(curl -s "$BASE_URL/video/status/$PROJECT_ID" \
-H "X-API-Key: $API_KEY")

STATUS=$(echo $STATUS_RESPONSE | jq -r '.status')
echo "Status: $STATUS"

if [ "$STATUS" = "completed" ]; then
echo "Video completed!"
break
elif [ "$STATUS" = "failed" ]; then
ERROR=$(echo $STATUS_RESPONSE | jq -r '.error')
echo "Error: $ERROR"
exit 1
fi

sleep 5
done

# 3. Download video
echo "Downloading video..."
DOWNLOAD_RESPONSE=$(curl -s "$BASE_URL/video/download/$PROJECT_ID" \
-H "X-API-Key: $API_KEY")

DOWNLOAD_URL=$(echo $DOWNLOAD_RESPONSE | jq -r '.downloadUrl')
curl -o "video-$PROJECT_ID.mp4" "$DOWNLOAD_URL"

echo "Downloaded: video-$PROJECT_ID.mp4"

Node.js

const fs = require('fs');
const https = require('https');

const API_KEY = 'rb_live_your_key_here';
const BASE_URL = 'https://reelbot.space/api/v1';

async function generateVideo(params) {
const response = await fetch(`${BASE_URL}/video/generate`, {
method: 'POST',
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify(params),
});

const data = await response.json();

if (!data.success) {
throw new Error(`Generation failed: ${data.message}`);
}

return data.projectId;
}

async function waitForCompletion(projectId, maxWaitMs = 600000) {
const startTime = Date.now();

while (Date.now() - startTime < maxWaitMs) {
const response = await fetch(`${BASE_URL}/video/status/${projectId}`, {
headers: { 'X-API-Key': API_KEY },
});

const data = await response.json();

console.log(`Status: ${data.status}`);

if (data.status === 'completed') {
return data;
}

if (data.status === 'failed') {
throw new Error(`Video failed: ${data.error}`);
}

await new Promise(resolve => setTimeout(resolve, 5000));
}

throw new Error('Timeout waiting for video');
}

async function downloadVideo(projectId, outputPath) {
const response = await fetch(`${BASE_URL}/video/download/${projectId}`, {
headers: { 'X-API-Key': API_KEY },
});

const { downloadUrl } = await response.json();

return new Promise((resolve, reject) => {
const file = fs.createWriteStream(outputPath);
https.get(downloadUrl, (response) => {
response.pipe(file);
file.on('finish', () => {
file.close();
resolve(outputPath);
});
}).on('error', (err) => {
fs.unlink(outputPath, () => {});
reject(err);
});
});
}

// Main execution
async function main() {
try {
console.log('Starting video generation...');

const projectId = await generateVideo({
videoType: 'narrated',
topic: '3 Morning Habits for Success',
script: 'Here are three morning habits that successful people swear by...',
voiceId: 'matthew',
brollKeys: [
'users/YOUR_USER_ID/b-roll/morning.mp4',
'users/YOUR_USER_ID/b-roll/exercise.mp4',
],
aspectRatio: '9:16',
scriptDuration: 30,
});

console.log(`Project ID: ${projectId}`);

console.log('Waiting for completion...');
await waitForCompletion(projectId);

console.log('Downloading video...');
const outputPath = await downloadVideo(projectId, `./video-${projectId}.mp4`);

console.log(`Downloaded: ${outputPath}`);
} catch (error) {
console.error('Error:', error.message);
process.exit(1);
}
}

main();

Python

import requests
import time
import sys

API_KEY = 'rb_live_your_key_here'
BASE_URL = 'https://reelbot.space/api/v1'

def generate_video(params):
"""Start video generation and return project ID."""
response = requests.post(
f'{BASE_URL}/video/generate',
headers={
'X-API-Key': API_KEY,
'Content-Type': 'application/json',
},
json=params,
)

data = response.json()

if not data.get('success', False) and 'projectId' not in data:
raise Exception(f"Generation failed: {data.get('message', 'Unknown error')}")

return data['projectId']

def wait_for_completion(project_id, max_wait_seconds=600):
"""Poll until video is complete or failed."""
start_time = time.time()

while time.time() - start_time < max_wait_seconds:
response = requests.get(
f'{BASE_URL}/video/status/{project_id}',
headers={'X-API-Key': API_KEY},
)

data = response.json()
status = data.get('status')

print(f'Status: {status}')

if status == 'completed':
return data

if status == 'failed':
raise Exception(f"Video failed: {data.get('error', 'Unknown error')}")

time.sleep(5)

raise Exception('Timeout waiting for video')

def download_video(project_id, output_path):
"""Download completed video to file."""
response = requests.get(
f'{BASE_URL}/video/download/{project_id}',
headers={'X-API-Key': API_KEY},
)

data = response.json()
download_url = data['downloadUrl']

video_response = requests.get(download_url, stream=True)

with open(output_path, 'wb') as f:
for chunk in video_response.iter_content(chunk_size=8192):
f.write(chunk)

return output_path

def main():
try:
print('Starting video generation...')

project_id = generate_video({
'videoType': 'narrated',
'topic': '3 Morning Habits for Success',
'script': 'Here are three morning habits that successful people swear by...',
'voiceId': 'matthew',
'brollKeys': [
'users/YOUR_USER_ID/b-roll/morning.mp4',
'users/YOUR_USER_ID/b-roll/exercise.mp4',
],
'aspectRatio': '9:16',
'scriptDuration': 30,
})

print(f'Project ID: {project_id}')

print('Waiting for completion...')
wait_for_completion(project_id)

print('Downloading video...')
output_path = download_video(project_id, f'./video-{project_id}.mp4')

print(f'Downloaded: {output_path}')

except Exception as e:
print(f'Error: {e}', file=sys.stderr)
sys.exit(1)

if __name__ == '__main__':
main()

Cinematic Video (No Narration)

curl -X POST https://reelbot.space/api/v1/video/generate \
-H "X-API-Key: rb_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"videoType": "cinematic",
"topic": "Urban Night Vibes",
"brollKeys": [
"users/YOUR_USER_ID/b-roll/city-lights.mp4",
"users/YOUR_USER_ID/b-roll/traffic-timelapse.mp4",
"users/YOUR_USER_ID/b-roll/neon-signs.mp4"
],
"musicKey": "shared/music/lofi-chill.mp3",
"aspectRatio": "9:16",
"scriptDuration": 15
}'

With Asset Trimming

curl -X POST https://reelbot.space/api/v1/video/generate \
-H "X-API-Key: rb_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"videoType": "narrated",
"topic": "Quick Cooking Tip",
"script": "Here is a quick tip that will change how you cook pasta forever.",
"voiceId": "joanna",
"brollKeys": [
"users/YOUR_USER_ID/b-roll/cooking-pasta.mp4",
"users/YOUR_USER_ID/b-roll/boiling-water.mp4"
],
"assetTrimSettings": {
"users/YOUR_USER_ID/b-roll/cooking-pasta.mp4": {
"startTime": 5.0,
"endTime": 12.0
},
"users/YOUR_USER_ID/b-roll/boiling-water.mp4": {
"startTime": 0,
"endTime": 6.5
}
},
"aspectRatio": "9:16",
"scriptDuration": 15
}'

Batch Processing

Generate Multiple Videos

const videos = [
{
topic: 'Tip 1: Wake Up Early',
script: 'The first tip is to wake up early...',
},
{
topic: 'Tip 2: Exercise Daily',
script: 'The second tip is to exercise daily...',
},
{
topic: 'Tip 3: Read More',
script: 'The third tip is to read more books...',
},
];

async function generateBatch(videos) {
const results = [];

for (const video of videos) {
console.log(`Generating: ${video.topic}`);

const projectId = await generateVideo({
videoType: 'narrated',
topic: video.topic,
script: video.script,
voiceId: 'joanna',
brollKeys: ['users/YOUR_USER_ID/b-roll/generic.mp4'],
aspectRatio: '9:16',
scriptDuration: 15,
});

results.push({ topic: video.topic, projectId });

// Respect rate limits: wait between requests
if (videos.indexOf(video) < videos.length - 1) {
console.log('Waiting before next request...');
await new Promise(r => setTimeout(r, 10000)); // 10 seconds
}
}

return results;
}

// Wait for all to complete
async function waitForAll(projectIds) {
const results = [];

for (const { topic, projectId } of projectIds) {
console.log(`Waiting for: ${topic}`);
const result = await waitForCompletion(projectId);
results.push({ topic, projectId, ...result });
}

return results;
}

Error Handling Example

async function safeGenerateVideo(params) {
try {
const response = await fetch(`${BASE_URL}/video/generate`, {
method: 'POST',
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify(params),
});

// Handle rate limiting
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || 60;
console.log(`Rate limited. Retry after ${retryAfter} seconds.`);
return { success: false, retryAfter: parseInt(retryAfter) };
}

// Handle quota exceeded
if (response.status === 402) {
console.log('Quota exceeded. Upgrade plan or wait for reset.');
return { success: false, quotaExceeded: true };
}

const data = await response.json();

// Handle validation errors
if (response.status === 400) {
console.log(`Validation error: ${data.message}`);
return { success: false, validationError: data.message };
}

// Handle auth errors
if (response.status === 401) {
console.log('Authentication failed. Check your API key.');
return { success: false, authError: true };
}

return { success: true, projectId: data.projectId };

} catch (error) {
console.error('Network error:', error.message);
return { success: false, networkError: error.message };
}
}

Integration: Zapier Webhook

// Zapier webhook handler (e.g., in a serverless function)
exports.handler = async (event) => {
const { topic, script } = JSON.parse(event.body);

const response = await fetch('https://reelbot.space/api/v1/video/generate', {
method: 'POST',
headers: {
'X-API-Key': process.env.REELBOT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
videoType: 'narrated',
topic,
script,
voiceId: 'joanna',
brollKeys: ['users/YOUR_USER_ID/b-roll/default.mp4'],
aspectRatio: '9:16',
scriptDuration: 30,
}),
});

const data = await response.json();

return {
statusCode: 200,
body: JSON.stringify({
projectId: data.projectId,
statusUrl: `https://reelbot.space/api/v1/video/status/${data.projectId}`,
}),
};
};

Next Steps

Error Handling — Handle edge cases gracefully

Rate Limits — Understand usage limits