Skip to content

Batch Video Production

Fresh

Overview

Scale video production by running multiple Creatify tasks in parallel with proper polling management, credit budgeting, and error handling.

Architecture

Batch Processing Pattern

Code Example: Batch URL-to-Video

python
import time
import requests
from concurrent.futures import ThreadPoolExecutor, as_completed

API_ID = "your-api-id"
API_KEY = "your-api-key"
HEADERS = {
    "X-API-ID": API_ID,
    "X-API-KEY": API_KEY,
    "Content-Type": "application/json"
}
BASE = "https://api.creatify.ai/api"


def check_credits():
    """Return remaining credits."""
    r = requests.get(f"{BASE}/workspace/remaining_credits/", headers=HEADERS)
    return r.json()["remaining_credits"]


def create_link(url):
    """Create a link object from a URL."""
    r = requests.post(f"{BASE}/links/", headers=HEADERS, json={"url": url})
    return r.json()


def create_video_task(link_id, aspect_ratio="9:16"):
    """Create a URL-to-video task."""
    r = requests.post(f"{BASE}/url_to_videos/", headers=HEADERS, json={
        "link_id": link_id,
        "aspect_ratio": aspect_ratio
    })
    return r.json()


def poll_task(task_id, interval=10, timeout=600):
    """Poll a single task until done or failed."""
    elapsed = 0
    while elapsed < timeout:
        r = requests.get(f"{BASE}/url_to_videos/{task_id}/", headers=HEADERS)
        result = r.json()
        if result["status"] == "done":
            return {"id": task_id, "status": "done", "output": result["output"]}
        if result["status"] == "failed":
            return {"id": task_id, "status": "failed",
                    "reason": result.get("failed_reason")}
        time.sleep(interval)
        elapsed += interval
    return {"id": task_id, "status": "timeout"}


def batch_generate(urls, aspect_ratio="9:16", max_parallel=5):
    """
    Generate videos for a batch of URLs.

    Args:
        urls: list of webpage URLs
        aspect_ratio: video aspect ratio
        max_parallel: max concurrent tasks
    """
    # Pre-flight: check credits
    credits = check_credits()
    estimated_cost = len(urls) * 5  # 5 credits per 30s, assuming 30s videos
    print(f"Credits available: {credits}")
    print(f"Estimated cost: {estimated_cost}")
    if credits < estimated_cost:
        raise ValueError(
            f"Insufficient credits: {credits} available, ~{estimated_cost} needed"
        )

    # Phase 1: Create links
    print(f"Creating {len(urls)} links...")
    links = []
    for url in urls:
        link = create_link(url)
        links.append(link)
        print(f"  Link: {link['id']} - {link.get('title', 'No title')}")

    # Phase 2: Create video tasks
    print(f"Creating {len(links)} video tasks...")
    tasks = []
    for link in links:
        task = create_video_task(link["id"], aspect_ratio)
        tasks.append(task)
        print(f"  Task: {task['id']} - {task['status']}")

    # Phase 3: Poll all tasks in parallel
    print(f"Polling {len(tasks)} tasks...")
    results = []
    with ThreadPoolExecutor(max_workers=max_parallel) as executor:
        futures = {
            executor.submit(poll_task, task["id"]): task["id"]
            for task in tasks
        }
        for future in as_completed(futures):
            result = future.result()
            results.append(result)
            print(f"  {result['id']}: {result['status']}")

    # Summary
    done = [r for r in results if r["status"] == "done"]
    failed = [r for r in results if r["status"] == "failed"]
    timeout = [r for r in results if r["status"] == "timeout"]

    print(f"\nResults: {len(done)} done, {len(failed)} failed, {len(timeout)} timeout")
    return results


# Usage
urls = [
    "https://example.com/product-1",
    "https://example.com/product-2",
    "https://example.com/product-3",
    "https://example.com/product-4",
    "https://example.com/product-5",
]

results = batch_generate(urls)

Credit Budget Management

ScenarioVideosDurationCredits/30sTotal Cost
Small batch530s each525 credits
Medium batch2030s each5100 credits
Large batch10030s each5500 credits
Preview + Render2030s each1+4100 credits

Error Handling Strategy

Error TypeStrategy
Single task failureLog error, continue other tasks, retry failed ones at the end
Rate limit (429)Implement exponential backoff, reduce parallelism
Insufficient creditsStop creating new tasks, wait for current to finish
Network timeoutRetry with longer timeout, reduce batch size
All tasks failingStop batch, investigate root cause

Scaling Tips

TIP

  1. Stagger creation -- Do not create 100 tasks simultaneously. Stagger by 1-2 seconds.
  2. Unified polling -- Poll all tasks in a single loop rather than per-task threads.
  3. Credit checkpoints -- Check remaining credits after every 10 completed tasks.
  4. Retry queue -- Failed tasks go to a retry queue with exponential backoff.
  5. Rate limits -- Respect API rate limits. Start with 5-10 parallel tasks and increase.

See Also