Skip to content

Video generation

Generate video clips from a text prompt and optional start and end frames with the asynchronous video task API.

This page explains how to generate video with Engy. It is intended for developers who create video clips from text prompts or images.

How video generation works

Video generation is asynchronous. It uses a task API on the same host and with the same API key as the other endpoints:

  1. You submit a task with a prompt.
  2. You poll the task until it succeeds or fails.
  3. You download the finished MP4 file.
EndpointDescription
POST /v2/video_generationSubmits a task.
GET /v2/query/video_generation/{task_id}Returns the status of a task.
GET /v2/query/video_generationLists your tasks from the last 7 days.
DELETE /v2/video_generation/{task_id}Cancels a queued task, or deletes a finished task.
GET /v2/video_generation/{task_id}/contentDownloads the video.

The available video model is MiniMax-H3. For details, see Models and pricing.

Every response contains a base_resp object. Its status_code is 0 on success. Error responses also contain the standard error object.

Generate a video

Submit a task

curl https://api.engy.ai/v2/video_generation \
  -H "Authorization: Bearer $ENGY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "MiniMax-H3",
    "content": [{"type": "text", "text": "A red fox trots across fresh snow at dawn"}],
    "duration": 6,
    "ratio": "16:9"
  }'

The response contains the task ID:

{
  "task_id": "9f1c2b7e4d6a4f0b8e3c5a7d9b1f2e4c",
  "status": "queued",
  "base_resp": {"status_code": 0, "status_msg": "success"}
}

Poll the task

curl https://api.engy.ai/v2/query/video_generation/$TASK_ID \
  -H "Authorization: Bearer $ENGY_API_KEY"

A task moves from queued to running, and then to succeeded or failed. A clip usually takes a few minutes after it starts running. Poll every 10 to 30 seconds.

When the task succeeds, task.content.url contains the download link:

{
  "task": {
    "task_id": "9f1c2b7e4d6a4f0b8e3c5a7d9b1f2e4c",
    "status": "succeeded",
    "model": "MiniMax-H3",
    "duration": 6,
    "ratio": "16:9",
    "resolution": "768P",
    "usage": {"video_seconds": 6.0},
    "content": {
      "url": "https://api.engy.ai/v2/video_generation/9f1c2b7e4d6a4f0b8e3c5a7d9b1f2e4c/content?token=...",
      "content_type": "video/mp4",
      "bytes": 4194304,
      "expires_at": 1792368000
    },
    "error": null
  },
  "base_resp": {"status_code": 0, "status_msg": "success"}
}

Download the video

curl -L -o clip.mp4 "$CONTENT_URL"

The link is signed and does not require an API key. It is valid for 24 hours, until expires_at. Poll the task again to get a new link.

You can also download the video at any time from GET /v2/video_generation/{task_id}/content with your API key. Both methods return a redirect to a short-lived storage link, so let your client follow redirects.

Complete example

generate_video.py
import os
import time

import httpx

BASE_URL = "https://api.engy.ai"
headers = {"Authorization": f"Bearer {os.environ['ENGY_API_KEY']}"}

submit = httpx.post(
    f"{BASE_URL}/v2/video_generation",
    headers=headers,
    json={
        "model": "MiniMax-H3",
        "content": [{"type": "text", "text": "A red fox trots across fresh snow at dawn"}],
        "duration": 6,
        "ratio": "16:9",
    },
)
submit.raise_for_status()
task_id = submit.json()["task_id"]

while True:
    time.sleep(15)
    task = httpx.get(
        f"{BASE_URL}/v2/query/video_generation/{task_id}", headers=headers
    ).json()["task"]
    if task["status"] in ("succeeded", "failed"):
        break

if task["status"] == "failed":
    raise RuntimeError(task["error"]["message"])

video = httpx.get(task["content"]["url"], follow_redirects=True)
video.raise_for_status()
with open("clip.mp4", "wb") as f:
    f.write(video.content)

Request parameters

ParameterTypeRequiredDescription
modelStringYesThe video model ID, such as MiniMax-H3.
contentArrayYesText items, which form the prompt, and optional image items for the start and end frames.
durationIntegerNoThe length of the clip, in whole seconds, from 4 to 15. Defaults to 5.
ratioStringNoadaptive, 21:9, 16:9, 4:3, 1:1, 3:4, or 9:16. Defaults to adaptive.
resolutionStringNo768P, which is the only supported value.
seedIntegerNoA seed for generation.

Engy joins the text items in content into one prompt. The prompt can contain at most 7,000 characters.

Set start and end frames

Add an image item with role set to first_frame to fix the opening shot. Add a second image with role set to last_frame to fix the closing shot. An image without a role is used as the first frame.

FIRST="data:image/jpeg;base64,$(base64 -w0 start.jpg)"

curl https://api.engy.ai/v2/video_generation \
  -H "Authorization: Bearer $ENGY_API_KEY" \
  -H "Content-Type: application/json" \
  -d @- <<JSON
{
  "model": "MiniMax-H3",
  "duration": 6,
  "content": [
    {"type": "text", "text": "The camera pulls back to reveal the whole valley"},
    {"type": "image_url", "image_url": {"url": "$FIRST"}, "role": "first_frame"}
  ]
}
JSON

On macOS, use base64 -i start.jpg instead of base64 -w0 start.jpg.

Frames have the following requirements:

  • Each frame is a Base64 data URI. Engy does not download images from URLs.
  • The format is JPEG, PNG, or WebP.
  • Each side is from 256 to 5,760 pixels.
  • The aspect ratio is from 0.4 to 2.5.
  • Each frame is at most 30 MB.

Reference images, reference video, and reference audio are not supported.

Limits

LimitValueStatus if exceeded
Prompt length7,000 characters400
Duration4 to 15 seconds, in whole seconds400
Resolution768P400
FramesOne first frame and one last frame400
Frame size30 MB each413
Open tasks20 queued or running tasks per account429

Notifications through callback_url are not supported. Poll the task for its status instead.

Manage tasks

List tasks

GET /v2/query/video_generation lists your tasks from the last 7 days, newest first. It accepts the following query parameters:

ParameterDescription
page_numThe page number. Defaults to 1.
page_sizeThe number of tasks per page, from 1 to 100. Defaults to 10.
statusReturns only tasks with this status: queued, running, succeeded, failed, or cancelled.
modelReturns only tasks for this model.
task_idsReturns only the tasks with these IDs, separated by commas.

Cancel or delete a task

curl -X DELETE https://api.engy.ai/v2/video_generation/$TASK_ID \
  -H "Authorization: Bearer $ENGY_API_KEY"
Task statusResult
queuedThe task is cancelled at no charge.
succeeded or failedThe task and its video file are deleted.
runningThe request fails with status 400. Wait for the task to finish.

Billing

Video is billed per second of video produced. For the rate, see the pricing page.

  • When Engy accepts a task, it reserves credit for the full requested duration. If your balance is insufficient, the request fails with status 402.
  • When the task succeeds, you are charged for the seconds produced, which task.usage.video_seconds reports.
  • A failed or cancelled task is not charged.

If the worker that runs a task stops responding, Engy queues the task again and retries it once before it fails.

Data handling

Zero data retention does not apply to video generation. The prompt and the finished video are stored with the task until you delete it. Frame images are discarded when the task finishes.