Skip to main content
Every job in the Clipzy ML Engine follows a defined state machine. Understanding these states helps you build reliable integrations and handle edge cases cleanly.

Status flow

queued → processing → completed
                    ↘ failed

         cancelled
StatusTerminalDescription
queuedNoThe job has been accepted and is waiting for a processing slot.
processingNoThe job is actively running through the pipeline stages.
completedYesAll stages finished successfully. Output is available.
failedYesA pipeline stage encountered an unrecoverable error.
cancelledYesThe job was cancelled by you before it completed.
Terminal statuses (completed, failed, cancelled) will not change again. Once a job reaches one of these states, it stays there.
You cannot restart a failed job. Submit a new job with the same parameters if you need to retry.

Status field reference

status
string
required
Current job status. One of queued, processing, completed, failed, cancelled.
progress_percent
number
required
Integer from 0 to 100 indicating how far through the pipeline the job has progressed. Advances monotonically — it never goes backward. Reaches 100 only when the job is completed.
current_stage
string
The pipeline stage currently executing. One of video_analysis, audio_analysis, motion_analysis, style_extraction, style_application, rendering. null when the job is queued, completed, failed, or cancelled.
error
object
Present only when status is failed. Contains stage (the pipeline stage where failure occurred) and message (a human-readable description of the error).

Progress and stages

As the job moves through the pipeline, current_stage reflects the active stage and progress_percent advances:
current_stageTypical progress_percent range
(queued, no stage)0
video_analysis1–20
audio_analysis21–35
motion_analysis36–55
style_extraction56–65
style_application66–85
rendering86–99
(completed)100
If you submitted a template-only job (style extraction without rendering), the job completes at the end of style_extraction and progress_percent jumps to 100 without entering style_application or rendering.

Detecting completion

There are two ways to know when a job is done: polling and webhooks.

Polling

Fetch the job status on a schedule until you reach a terminal status:
GET /api/v1/jobs/{job_id}
A simple polling loop looks like this:
import time
import requests

def wait_for_job(base_url: str, job_id: str) -> dict:
    url = f"{base_url}/api/v1/jobs/{job_id}"
    terminal = {"completed", "failed", "cancelled"}

    while True:
        response = requests.get(url)
        job = response.json()["data"]

        print(f"Status: {job['status']} ({job['progress_percent']}%)")

        if job["status"] in terminal:
            return job

        time.sleep(5)
Poll every 5 seconds for short jobs (under 2 minutes). For longer jobs, use exponential backoff starting at 5 seconds and capping at 30 seconds to avoid rate limits.

Webhooks

Configure a webhook URL when creating a job. The engine sends a POST request to your endpoint when the job reaches any terminal status.
POST /api/v1/jobs
Content-Type: application/json

{
  "video_id": "vid_abc123",
  "webhook_url": "https://your-app.example.com/hooks/clipzy"
}
The webhook payload contains the job result fields:
{
  "job_id": "job_abc123",
  "status": "completed",
  "progress_percent": 100,
  "output_video_url": "file:///storage/job_abc123/output.mp4",
  "processing_time_seconds": 272.4
}
Respond to webhook requests with a 200 status within 10 seconds. If your endpoint times out or returns a non-2xx response, the engine retries with exponential backoff up to 3 times.
See the Webhooks guide for a complete integration example.