Skip to main content
We’ve updated video generation to use an asynchronous job-based Queue API. This change improves reliability, allows for better timeout handling, and provides visibility into job progress. The synchronous /v1/generate/ endpoints for video are now deprecated in favor of the new /v1/jobs/ endpoints.

What Changed

AspectBefore (Generate API)After (Queue API)
Endpoint/v1/generate/lucy-pro-t2v/v1/jobs/lucy-pro-t2v
Request typeSynchronous (blocking)Asynchronous (non-blocking)
ResponseDirect video binaryJob ID for polling
Timeout handlingHTTP timeout on long requestsPoll until completion (10 min max)
Progress visibilityNoneStatus updates (pending, processing, completed, failed)

JavaScript SDK

The JavaScript SDK now uses client.queue instead of client.generate for video generation.

Before

import { createDecartClient, models } from "@decartai/sdk";
import { writeFileSync } from "fs";

const client = createDecartClient({ apiKey: "your-api-key" });

// Synchronous - blocks until video is ready
const video = await client.generate({
  model: models.video("lucy-pro-t2v"),
  prompt: "A serene lake at sunset",
});

writeFileSync("output.mp4", Buffer.from(await video.arrayBuffer()));

After

import { createDecartClient, models } from "@decartai/sdk";
import { writeFileSync } from "fs";

const client = createDecartClient({ apiKey: "your-api-key" });

// Asynchronous - submit and poll for completion
const result = await client.queue.submitAndPoll({
  model: models.video("lucy-pro-t2v"),
  prompt: "A serene lake at sunset",
  onStatusChange: (job) => console.log(`Status: ${job.status}`),
});

if (result.status === "completed") {
  writeFileSync("output.mp4", Buffer.from(await result.data.arrayBuffer()));
}
For custom polling logic, you can manually control the submit/poll/result flow:
// Submit job
const job = await client.queue.submit({
  model: models.video("lucy-pro-t2v"),
  prompt: "A serene lake at sunset",
});

console.log(`Job ID: ${job.job_id}`);

// Poll for status
while (true) {
  const status = await client.queue.status(job.job_id);
  console.log(`Status: ${status.status}`);

  if (status.status === "completed") {
    const result = await client.queue.result(job.job_id);
    writeFileSync("output.mp4", Buffer.from(await result.data.arrayBuffer()));
    break;
  } else if (status.status === "failed") {
    console.error("Job failed");
    break;
  }

  await new Promise(r => setTimeout(r, 2000));
}

JavaScript Queue API Reference

Full documentation for the JavaScript Queue API

Python SDK

The Python SDK now uses client.queue instead of client.generate for video generation.

Before

import asyncio
from decart import DecartClient, models

async def generate():
    async with DecartClient(api_key="your-api-key") as client:
        # Synchronous - blocks until video is ready
        video = await client.generate({
            "model": models.video("lucy-pro-t2v"),
            "prompt": "A serene lake at sunset",
        })

        with open("output.mp4", "wb") as f:
            f.write(video)

asyncio.run(generate())

After

import asyncio
from decart import DecartClient, models

async def generate():
    async with DecartClient(api_key="your-api-key") as client:
        # Asynchronous - submit and poll for completion
        result = await client.queue.submit_and_poll({
            "model": models.video("lucy-pro-t2v"),
            "prompt": "A serene lake at sunset",
            "on_status_change": lambda job: print(f"Status: {job.status}"),
        })

        if result.status == "completed":
            with open("output.mp4", "wb") as f:
                f.write(result.data)

asyncio.run(generate())
For custom polling logic, you can manually control the submit/poll/result flow:
import asyncio

# Submit job
job = await client.queue.submit({
    "model": models.video("lucy-pro-t2v"),
    "prompt": "A serene lake at sunset",
})

print(f"Job ID: {job.job_id}")

# Poll for status
while True:
    status = await client.queue.status(job.job_id)
    print(f"Status: {status.status}")

    if status.status == "completed":
        result = await client.queue.result(job.job_id)
        with open("output.mp4", "wb") as f:
            f.write(result.data)
        break
    elif status.status == "failed":
        print("Job failed")
        break

    await asyncio.sleep(2)

Python Queue API Reference

Full documentation for the Python Queue API

HTTP / REST API

The REST API now uses a three-step flow: submit, poll, and retrieve.

Before

# Single request - blocks until complete (could timeout on long generations)
curl -X POST https://api.decart.ai/v1/generate/lucy-pro-t2v \
  -H "X-API-KEY: $DECART_API_KEY" \
  -F "prompt=A serene lake at sunset" \
  --output output.mp4

After

# Step 1: Submit job
JOB_ID=$(curl -s -X POST https://api.decart.ai/v1/jobs/lucy-pro-t2v \
  -H "X-API-KEY: $DECART_API_KEY" \
  -F "prompt=A serene lake at sunset" | jq -r '.job_id')

echo "Job submitted: $JOB_ID"

# Step 2: Poll for status
while true; do
  STATUS=$(curl -s -H "X-API-KEY: $DECART_API_KEY" \
    https://api.decart.ai/v1/jobs/$JOB_ID | jq -r '.status')
  echo "Status: $STATUS"
  [ "$STATUS" = "completed" ] && break
  [ "$STATUS" = "failed" ] && exit 1
  sleep 2
done

# Step 3: Download result
curl -H "X-API-KEY: $DECART_API_KEY" \
  https://api.decart.ai/v1/jobs/$JOB_ID/content --output output.mp4

Endpoint mapping

Old EndpointNew Endpoint
POST /v1/generate/lucy-pro-t2vPOST /v1/jobs/lucy-pro-t2v
POST /v1/generate/lucy-pro-i2vPOST /v1/jobs/lucy-pro-i2v
POST /v1/generate/lucy-pro-v2vPOST /v1/jobs/lucy-pro-v2v
POST /v1/generate/lucy-dev-i2vPOST /v1/jobs/lucy-dev-i2v
POST /v1/generate/lucy-fast-v2vPOST /v1/jobs/lucy-fast-v2v

New endpoints for job management

EndpointDescription
GET /v1/jobs/{job_id}Get job status
GET /v1/jobs/{job_id}/contentDownload completed video

Key Differences

Error handling

The Queue API provides more granular error information through job status:
const result = await client.queue.submitAndPoll({
  model: models.video("lucy-pro-t2v"),
  prompt: "A serene lake at sunset",
});

if (result.status === "failed") {
  console.error(`Generation failed: ${result.error}`);
}

Progress tracking

Monitor job progress with status callbacks:
const result = await client.queue.submitAndPoll({
  model: models.video("lucy-pro-t2v"),
  prompt: "A serene lake at sunset",
  onStatusChange: (job) => {
    // Called when status changes: pending -> processing -> completed
    updateProgressUI(job.status);
  },
});

FAQ

The old synchronous endpoints for video generation are deprecated. Image generation still uses /v1/generate/.
Yes, make sure you’re using the latest version of the SDK:
  • JavaScript: npm install @decartai/sdk@latest
  • Python: pip install decart --upgrade
Image generation continues to use the synchronous Process API (client.process in SDKs, /v1/generate/ for REST). Only video generation has moved to the Queue API.