Create a video using an agent template
Table of contents
June 30, 2025 (August 21, 2025)
- Request Headers
- Response Headers
- Request Body
- Responses
- Model
Content-Type: text/event-stream
- Examples
- Try It
Create videos using MiniMax agent templates with predefined prompts and input requirements. On average, it takes 2 to 7 minutes for the agent to complete generation. The longer the duration of the result video, the longer it will take to generate. Videos longer than 15 seconds on average can take up to 15 minutes to generate.
Note: This endpoint returns a real-time streaming response (Content-Type: multipart/form-data
) that provides live progress updates during video generation.
Use hailuoai.video account to generate videos, see Setup MiniMax for details.
To browse available templates use GET videos/agent-templates.
https://api.useapi.net/v1/minimax/videos/agent-create
Request Headers
Authorization: Bearer {API token}
Content-Type: application/json
# Alternatively you can use multipart/form-data
# Content-Type: multipart/form-data
Response Headers
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
API token
is required, see Setup useapi.net for details.
Request Body
{
"account": "Optional MiniMax API account",
"templateId": "Required template ID",
"prompt": "Optional text prompt",
"fileID": "user:user_id-minimax:account-file:file_id",
"ossPath": "Required OSS path when using fileID",
"replyUrl": "Place your call back URL here",
"replyRef": "Place your reference id here",
"maxJobs": 1
}
-
account
is optional, if not specified API will randomly select account from available accounts. -
templateId
is required, the ID of the agent template to use. Get available templates from GET videos/agent-templates. -
prompt
is optional, text input for templates that require text prompts. Check template requirements using GET videos/agent-templates/?templateId=templateId
with the specifictemplateId
. fileID
is optional, required for templates that need image inputs:- fileID of image uploaded via POST /files
- fileID of previously uploaded image retrieved via GET /files
- fileID of previously uploaded character retrieved via GET videos/characters
- fileID of image generated via POST images/create.
-
ossPath
is required when usingfileID
, the OSS path / url for the uploaded file. Cannot be provided withoutfileID
. -
replyUrl
is optional, if not provided value from useapi.net account will be used.
Place here your callback URL. API will call the providedreplyUrl
once MiniMax video completed or failed.
Maximum length 1024 characters. -
replyRef
is optional, place here your reference id which will be stored and returned along with this MiniMax video response / result.
Maximum length 1024 characters. maxJobs
is optional, if not specified value from accounts/account will be used.
Valid range: 1…10.
Responses
-
Returns a streaming response (
Content-Type: text/event-stream
) with real-time progress updates. The stream contains multiple data events showing the video generation process from start to finish.See server-sent events to learn more about events format.
data: {"status":"created","videoId":"user:1234-minimax:1234567-video:7654321","projectID":"…","chatID":"…","message":{"msgContent":"Futuristic sports car","msgType":1},"code":200,"timestamp":1755800001000} data: {"status":"connected","videoId":"user:1234-minimax:1234567-video:7654321","projectID":"…","chatID":"…","code":200,"timestamp":1755800002000} data: {"status":"heartbeat","timestamp":1755800012000} data: {"status":"progress","type":1,"message":{"msgContent":"Generating image...","msgType":2},"timestamp":1755800015000} data: {"status":"progress","type":2,"message":{"attachmentInfo":{"attachments":[{"file":{"fileName":"processing"},"status":2}]}},"timestamp":1755800017000} data: {"status":"progress","type":2,"message":{"attachmentInfo":{"attachments":[{"file":{"fileName":"car.png","fileUrl":"https://cdn.hailuoai.video/moss/prod/.../car.png"},"status":3}]}},"timestamp":1755800025000} data: {"status":"progress","type":1,"message":{"msgContent":"Generating video...","msgType":2},"timestamp":1755800026000} data: {"status":"progress","type":2,"message":{"attachmentInfo":{"type":3,"attachments":[{"file":{"fileName":"processing"},"status":2}]}},"timestamp":1755800028000} data: {"status":"progress","type":2,"message":{"attachmentInfo":{"type":3,"attachments":[{"file":{"fileName":"final_video.mp4","fileUrl":"https://cdn.hailuoai.video/moss/prod/.../final.mp4"},"status":3}]}},"timestamp":1755800055000} data: {"status":"progress","type":3,"isFinished":true,"recTemplateList":[{"id":"template_vlog_1","name":"Vlog Interview"},{"id":"template_tf_2","name":"Transformers"}],"timestamp":1755800056000} data: {"status":"finished","videoId":"user:1234-minimax:1234567-video:7654321","projectID":"…","chatID":"…","message":{"msgContent":"Futuristic sports car","msgType":1},"code":200,"timestamp":1755800057000}
Use the
videoId
from the stream event with"status":"finished"
or"status":"created"
to retrieve video status and results using GET /videos/videoId
. -
{ "error": "<Error message>" }
-
{ "error": "Unauthorized" }
-
{ "error": "The video or template you are trying to use does not exist or has been deleted." }
Model Content-Type: text/event-stream
See server-sent events to learn more about events format.
data:<JSON Data>
data:<JSON Data>
…
JSON Data Model
{ // TypeScript, all fields are optional
status?: 'created' | 'connected' | 'heartbeat' | 'progress' | 'finished' // Event status
videoId?: string // Use GET /videos/<videoId> to retrieve results
timestamp?: number // Event timestamp in milliseconds
projectID?: string // Project identifier
sectionID?: string // Section identifier within the project
chatID?: string // Chat session identifier
code?: number // Response code, e.g., 200
type?: 1 | 2 | 3 // Progress type. 1: Text/Tool, 2: Attachment, 3: Recommendations
needUserInput?: boolean // Flag indicating if user input is required
isFinished?: boolean // Flag indicating if the entire process is complete
errCode?: number // Error code, 0 for success
errMsg?: string // Error message string
/** The main message payload, can be null during certain events */
message?: {
msgId: string // Unique message ID
parentMsgId?: string // ID of the parent message
msgType?: 1 | 2 // Message type. 1: User, 2: System
isQuota?: boolean // Quota usage flag
timestamp?: number // Message creation timestamp
msgContent?: string // Text content of the message
files?: { // User-uploaded files
fileName: string
fileUrl: string
posterUrl: string
type: string
extra: Record<string, never>
}[]
toolCall?: { // System tool call details
toolName: string
toolCallStatus: 1 | 2 // Tool status. 1: Started, 2: Finished
toolCallArgs: string // Tool arguments as a JSON string
}
attachmentInfo?: { // Generated media attachments
attachmentInfoID: string
type?: 1 | 2 | 3 // Attachment type. 1: Image, 2: Video, 3: Final Composite
attachments: {
attachmentID: string
type?: number
file: {
fileName: string
fileUrl: string
posterUrl: string
type: string
extra?: {
height?: string
width?: string
url?: string
path?: string
no_watermark_url?: string
watermark_url?: string
duration?: string
fps?: string
frames?: string // A JSON string of frame URLs
task_id?: string
vendor?: string
} | Record<string, never>
}
text?: string
status?: 2 | 3 // Generation status. 2: Processing, 3: Complete
extra?: Record<string, never>
subAttachments?: []
}[]
createTime?: number
attachmentInfoUrl?: string
extra?: Record<string, never>
status?: number
}
} | null
}
Examples
-
Expand
JavaScript Streaming Example
const templateId = "1122334455667788"; const prompt = "text prompt"; const token = "API token"; const response = await fetch('https://api.useapi.net/v1/minimax/videos/agent-create', { method: 'POST', headers: { 'Authorization': `Bearer ${token}` }, body: new FormData([['templateId', templateId], ['prompt', prompt]]) }); if (!response.ok) { const errorText = await response.text(); throw new Error(`HTTP ${response.status}: ${errorText}`); } let videoId = null; const reader = response.body.getReader(); const decoder = new TextDecoder("utf-8"); let buffer = ""; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); const lines = buffer.split("\n"); buffer = lines.pop(); for (const line of lines) { if (line.startsWith("data:")) { try { const json = JSON.parse(line.slice(5).trim()); console.log("Stream event:", json); if (json.videoId && !videoId) { videoId = json.videoId; console.log("Video ID:", videoId); } if (json.status === 'finished') { console.log("Generation completed!"); break; } } catch (e) { console.error("Failed to parse JSON:", e); } } } } console.log("Final video ID:", videoId);
-
Expand
Python Streaming Example
import requests import json template_id = "1122334455667788" prompt = "text prompt" token = "API token" data = { 'templateId': template_id, 'prompt': prompt } response = requests.post( 'https://api.useapi.net/v1/minimax/videos/agent-create', headers={'Authorization': f'Bearer {token}'}, data=data, stream=True ) if not response.ok: print(f"HTTP Error {response.status_code}: {response.text}") exit(1) video_id = None for line in response.iter_lines(decode_unicode=True): if line and line.startswith("data:"): try: json_data = json.loads(line[5:].strip()) print("Stream event:", json_data) if json_data.get("videoId") and not video_id: video_id = json_data["videoId"] print(f"Video ID: {video_id}") if json_data.get("status") == "finished": print("Generation completed!") break except json.JSONDecodeError as e: print(f"Failed to parse JSON: {e}") print(f"Final video ID: {video_id}")
-
curl -H "Accept: text/event-stream" \ -H "Authorization: Bearer …" \ -X POST "https://api.useapi.net/v1/minimax/videos/agent-create" \ -d "templateId=1122334455667788" \ -d "prompt=text prompt" \ --no-buffer