GET /api/status/
Retrieves the current status, logs, and results for a processing job. Use this endpoint to poll for completion after submitting a video via /api/process.
Request
The unique job identifier returned from /api/process
Response
Current job state: queued, processing, completed, or failed
Array of log messages tracking job progress
Processing results (only present when status is completed)
Array of extracted viral clips with metadata
Relative URL to access the clip video file
AI-generated viral title for the clip
result.clips[].video_description_for_tiktok
TikTok-optimized caption with hashtags
result.clips[].video_description_for_instagram
Instagram Reels caption with hashtags
result.clips[].video_title_for_youtube_short
YouTube Shorts title (max 100 characters)
Start timestamp in original video (seconds)
End timestamp in original video (seconds)
result.clips[].virality_score
AI-assigned virality score (0-100)
API cost breakdown for this job
result.cost_analysis.total_cost
Total estimated cost in USD
Status Values
| Status | Description |
|---|
queued | Job is waiting for an available worker slot |
processing | Worker is actively processing the video |
completed | All clips extracted successfully |
failed | Processing encountered an error (check logs) |
Incremental Updates
The API provides real-time updates during processing. Poll every 2-5 seconds to get:
- Live log entries (stdout from main.py)
- Partial results as clips finish rendering
- Cost analysis updates
The result.clips array populates incrementally as clips finish. You can display partial results before the job completes.
Error Codes
| Code | Description |
|---|
| 404 | Job ID not found (expired or invalid) |
Examples
Poll for Completion
curl http://localhost:8000/api/status/550e8400-e29b-41d4-a716-446655440000
Response (Queued):
{
"status": "queued",
"logs": [
"Job 550e8400-e29b-41d4-a716-446655440000 queued."
],
"result": null
}
Response (Processing):
{
"status": "processing",
"logs": [
"Job 550e8400-e29b-41d4-a716-446655440000 queued.",
"Job started by worker.",
"Downloading video from YouTube...",
"Transcribing audio with Whisper...",
"Detecting scenes with PySceneDetect...",
"Analyzing viral moments with Gemini AI..."
],
"result": null
}
Response (Completed):
{
"status": "completed",
"logs": [
"Job 550e8400-e29b-41d4-a716-446655440000 queued.",
"Job started by worker.",
"...",
"Process finished successfully."
],
"result": {
"clips": [
{
"video_url": "/videos/550e8400-e29b-41d4-a716-446655440000/video_123_clip_1.mp4",
"title": "Mind-Blowing AI Secret!",
"video_description_for_tiktok": "This AI trick will change everything! #ai #tech #viral",
"video_description_for_instagram": "You won't believe what AI can do now 🤯 #ai #tech #reels",
"video_title_for_youtube_short": "AI Secret That Shocked Everyone",
"start": 45.2,
"end": 68.5,
"virality_score": 87
},
{
"video_url": "/videos/550e8400-e29b-41d4-a716-446655440000/video_123_clip_2.mp4",
"title": "This Changes Everything",
"video_description_for_tiktok": "Wait for the ending 😱 #viral #mindblown",
"video_description_for_instagram": "The plot twist at the end! 🔥 #viral #trending",
"video_title_for_youtube_short": "The Ending Will Shock You",
"start": 120.0,
"end": 155.3,
"virality_score": 92
}
],
"cost_analysis": {
"total_cost": 0.0042,
"gemini_api_calls": 3,
"whisper_duration_seconds": 180
}
}
}
Response (Failed):
{
"status": "failed",
"logs": [
"Job 550e8400-e29b-41d4-a716-446655440000 queued.",
"Job started by worker.",
"Downloading video from YouTube...",
"Process failed with exit code 1",
"Execution error: yt-dlp download failed"
],
"result": null
}
Python Polling Loop
import requests
import time
job_id = "550e8400-e29b-41d4-a716-446655440000"
while True:
response = requests.get(f"http://localhost:8000/api/status/{job_id}")
data = response.json()
print(f"Status: {data['status']}")
if data['status'] == 'completed':
clips = data['result']['clips']
print(f"✅ Generated {len(clips)} clips!")
for i, clip in enumerate(clips):
print(f" Clip {i+1}: {clip['title']}")
break
elif data['status'] == 'failed':
print("❌ Processing failed:")
print("\n".join(data['logs'][-5:])) # Last 5 log lines
break
time.sleep(3) # Poll every 3 seconds
JavaScript Polling with async/await
const pollStatus = async (jobId) => {
while (true) {
const response = await fetch(`http://localhost:8000/api/status/${jobId}`);
const data = await response.json();
console.log('Status:', data.status);
if (data.status === 'completed') {
console.log('✅ Clips ready:', data.result.clips);
return data.result;
}
if (data.status === 'failed') {
console.error('❌ Processing failed:', data.logs);
throw new Error('Job failed');
}
// Update UI with logs
data.logs.forEach(log => console.log(log));
await new Promise(resolve => setTimeout(resolve, 3000));
}
};
// Usage
try {
const result = await pollStatus('550e8400-e29b-41d4-a716-446655440000');
console.log('Processing complete!', result);
} catch (error) {
console.error('Job failed:', error);
}
Next Steps
Once a job completes: