Documentation Index
Fetch the complete documentation index at: https://mintlify.com/DecartAI/sdk/llms.txt
Use this file to discover all available pages before exploring further.
Method Signature
submitAndPoll<T extends VideoModelDefinition>(
options: QueueSubmitAndPollOptions<T>
): Promise<QueueJobResult>
Submit a job and automatically poll until completion. Returns a result object with status and does not throw on failure.
Parameters
options
QueueSubmitAndPollOptions<T>
required
Configuration object for job submission and pollingmodel
VideoModelDefinition
required
The video model definition to use. Access models via models.video().Supported models:
lucy-dev-i2v - image-to-video (Dev quality)
lucy-fast-v2v - video-to-video (Fast quality)
lucy-pro-t2v - text-to-video (Pro quality)
lucy-pro-i2v - image-to-video (Pro quality)
lucy-pro-v2v - video-to-video (Pro quality)
lucy-pro-flf2v - first-last-frame-to-video (Pro quality)
lucy-motion - motion-based image-to-video
lucy-restyle-v2v - video restyling
Text prompt for generation (required for text-to-video models)
Input file (image or video). Accepts:
File object
Blob object
ReadableStream
- URL string
URL object
Required for image-to-video and video-to-video models. Start frame image for first-last-frame models (lucy-pro-flf2v)
End frame image for first-last-frame models (lucy-pro-flf2v)
Reference image for style or appearance guidance (model-specific)
onStatusChange
(job: JobStatusResponse) => void
Callback invoked when job status changes during polling. Receives the full job status response object with job_id and status fields.
Optional AbortSignal for canceling the request and polling
Returns
Promise that resolves with a discriminated union based on job outcomeCompleted Job
Job completed successfully
Unique identifier for the job
The generated video as a Blob. Can be used with URL.createObjectURL() for playback.
Failed Job
Job failed during processing
Unique identifier for the job
Error message describing why the job failed
Examples
Basic Usage
import { createDecartClient, models } from "@decart-ai/decart";
const client = createDecartClient({
apiKey: process.env.DECART_API_KEY,
});
const result = await client.queue.submitAndPoll({
model: models.video("lucy-pro-t2v"),
prompt: "A beautiful sunset over the ocean"
});
if (result.status === "completed") {
const videoUrl = URL.createObjectURL(result.data);
videoElement.src = videoUrl;
console.log(`Video ready: ${videoUrl}`);
} else {
console.error("Job failed:", result.error);
}
With Status Updates
const result = await client.queue.submitAndPoll({
model: models.video("lucy-pro-t2v"),
prompt: "A cat playing piano",
onStatusChange: (job) => {
console.log(`Job ${job.job_id}: ${job.status}`);
// Update UI with progress
updateProgressBar(job.status);
}
});
if (result.status === "completed") {
console.log("Video generation completed!");
displayVideo(result.data);
} else {
console.error("Generation failed:", result.error);
showErrorMessage(result.error);
}
Image-to-Video
const file = document.querySelector('input[type="file"]').files[0];
const result = await client.queue.submitAndPoll({
model: models.video("lucy-pro-i2v"),
prompt: "Animate with flowing water",
data: file,
onStatusChange: (job) => {
console.log(`Status: ${job.status}`);
}
});
if (result.status === "completed") {
const videoUrl = URL.createObjectURL(result.data);
document.querySelector("video").src = videoUrl;
}
Video-to-Video
const result = await client.queue.submitAndPoll({
model: models.video("lucy-restyle-v2v"),
prompt: "Convert to anime style",
data: "https://example.com/input-video.mp4",
onStatusChange: (job) => {
statusDisplay.textContent = `Status: ${job.status}`;
}
});
if (result.status === "completed") {
saveVideo(result.data, "output.mp4");
} else {
alert(`Processing failed: ${result.error}`);
}
With Cancellation
const controller = new AbortController();
// Start job with ability to cancel
const resultPromise = client.queue.submitAndPoll({
model: models.video("lucy-pro-t2v"),
prompt: "A beautiful sunset",
signal: controller.signal,
onStatusChange: (job) => {
console.log(`Current status: ${job.status}`);
}
});
// Cancel button handler
cancelButton.onclick = () => {
controller.abort();
console.log("Job cancelled");
};
try {
const result = await resultPromise;
if (result.status === "completed") {
displayVideo(result.data);
}
} catch (error) {
if (error.name === "AbortError") {
console.log("Job was cancelled by user");
} else {
console.error("Error:", error);
}
}
Discriminated Union Pattern
const result = await client.queue.submitAndPoll({
model: models.video("lucy-pro-t2v"),
prompt: "A majestic mountain landscape"
});
// TypeScript knows the shape based on status
switch (result.status) {
case "completed":
// TypeScript knows result.data is available here
console.log("Video blob size:", result.data.size);
playVideo(result.data);
break;
case "failed":
// TypeScript knows result.error is available here
console.error("Failed:", result.error);
showErrorNotification(result.error);
break;
}
Error Handling
try {
const result = await client.queue.submitAndPoll({
model: models.video("lucy-pro-t2v"),
prompt: "A serene lake at dawn"
});
// Check the discriminated union
if (result.status === "completed") {
handleSuccess(result.data);
} else {
// Job failed but didn't throw
handleFailure(result.error);
}
} catch (error) {
// Network errors, validation errors, or abort errors
if (error.name === "AbortError") {
console.log("Request was cancelled");
} else if (error.code === "INVALID_INPUT") {
console.error("Invalid inputs:", error.message);
} else if (error.code === "NETWORK_ERROR") {
console.error("Network error:", error.message);
} else {
console.error("Unexpected error:", error);
}
}
Notes
- This method does not throw when a job fails during processing. Instead, it returns a result object with
status: "failed" and an error field.
- Exceptions are only thrown for network errors, invalid inputs, or when the request is aborted.
- The
onStatusChange callback is invoked immediately after submission with the initial status, and then periodically during polling.
- Polling continues until the job reaches
"completed" or "failed" status.
- Only video models support the queue API. For image models, use
client.process.generate().
- For more control over polling, use
client.queue.submit() followed by manual status checks.
See Also