Skip to main content
POST
/
v1
/
video_generation
Video Generation
curl --request POST \
  --url https://api.minimax.io/v1/video_generation \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: <content-type>' \
  --data '
{
  "prompt": "A little girl grow up.",
  "first_frame_image": "https://filecdn.minimax.chat/public/fe9d04da-f60e-444d-a2e0-18ae743add33.jpeg",
  "last_frame_image": "https://filecdn.minimax.chat/public/97b7cd08-764e-4b8b-a7bf-87a0bd898575.jpeg",
  "model": "MiniMax-Hailuo-02",
  "duration": 6,
  "resolution": "1080P"
}
'
{
  "task_id": "106916112212032",
  "base_resp": {
    "status_code": 0,
    "status_msg": "success"
  }
}

Authorizations

Authorization
string
header
required

HTTP: Bearer Auth

Headers

Content-Type
enum<string>
default:application/json
required

The media type of the request body. Must be set to application/json to ensure the data is sent in JSON format.

Available options:
application/json

Body

application/json
model
enum<string>
required

Model name. Supported values: MiniMax-Hailuo-02.

Note: First & last frame generation does not support 512P resolution.

Available options:
MiniMax-Hailuo-02
last_frame_image
string
required

Image to be used as the last frame of the video. Supports public URLs or Base64-encoded Data URLs (data:image/jpeg;base64,...).

  • Image requirements:
    • Formats: JPG, JPEG, PNG, WebP
    • Size: < 20MB
    • Dimensions: Short side > 300px; Aspect ratio between 2:5 and 5:2

⚠️ Video resolution is determined by the first frame. If first and last frames differ in size, the last frame will be cropped to match the first

prompt
string

Text description of the video, up to 2000 characters. For MiniMax-Hailuo-02, you can use [commands] syntax for camera movement control. Camera movement commands can be embedded in prompt using the [command] format for precise control.

  • Supported 15 camera commands:

    • Truck: [Truck left], [Truck right]
    • Pan: [Pan left], [Pan right]
    • Push: [Push in], [Pull out]
    • Pedestal: [Pedestal up], [Pedestal down]
    • Tilt: [Tilt up], [Tilt down]
    • Zoom: [Zoom in], [Zoom out]
    • Shake: [Shake]
    • Follow: [Tracking shot]
    • Static: [Static shot]
  • Usage rules:

    • Combined movements: Multiple commands inside one [] take effect simultaneously (e.g., [Pan left,Pedestal up]). Recommended max: 3.
    • Sequential movements: Commands appear in order, e.g., "...[Push in], then...[Push out]".
    • Natural language: Free-form descriptions also work, but explicit commands yield more accurate results.
first_frame_image
string

Image to be used as the first frame of the video. Supports public URLs or Base64-encoded Data URLs (data:image/jpeg;base64,...).

  • Image requirements:
    • Formats: JPG, JPEG, PNG, WebP
    • Size: < 20MB
    • Dimensions: Short side > 300px; Aspect ratio between 2:5 and 5:2

⚠️ Video resolution follows the first frame image

prompt_optimizer
boolean

Whether to automatically optimize the prompt. Defaults to true. Set to false for more precise control.

duration
integer

Video duration (in seconds). Default: 6. Available values for first & last frame generation depend on resolution:

Model768P1080P
MiniMax-Hailuo-026 or 106
resolution
enum<string>

Video resolution. First & last frame generation supports 768P and 1080P:

Model6s10s
MiniMax-Hailuo-02768P (default), 1080P768P
Available options:
768P,
1080P
callback_url
string

A callback URL to receive asynchronous task status updates.

  1. Validation: Once configured, MiniMax sends a POST request with a challenge field. Your server must echo this value within 3s to validate.
  2. Updates: After validation, MiniMax pushes status updates when the task changes. Response structure matches the Query Video Generation Task API.

Callback status values:

  • "processing" – Task in progress
  • "success" – Task completed successfully
  • "failed" – Task failed
from fastapi import FastAPI, HTTPException, Request
import json

app = FastAPI()

@app.post("/get_callback")
async def get_callback(request: Request):
try:
json_data = await request.json()
challenge = json_data.get("challenge")
if challenge is not None:
# Validation request, echo back challenge
return {"challenge": challenge}
else:
# Status update request, handle accordingly
# {
# "task_id": "115334141465231360",
# "status": "success",
# "file_id": "205258526306433",
# "base_resp": {
# "status_code": 0,
# "status_msg": "success"
# }
# }
return {"status": "success"}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))

if __name__ == "__main__":
import uvicorn
uvicorn.run(
app, # Required
host="0.0.0.0", # Required
port=8000, # Required, port can be customized
# ssl_keyfile="yourname.yourDomainName.com.key", # Optional, enable if using SSL
# ssl_certfile="yourname.yourDomainName.com.key", # Optional, enable if using SSL
)

Response

200 - application/json
task_id
string

The video generation task ID, used for querying status.

base_resp
object