Video Generation API

Video generation API reference

This reference describes requests, responses, and errors for developers using the video_generation service.

The compatibility baseline is the official MiniMax documentation for video generation and file upload.

Every request sends Authorization: Bearer <API_KEY> in the header. Request bodies use application/json except for file upload.

Overview

MethodPathPurpose
POST/v2/video_generationCreate a video generation task
GET/v2/query/video_generation/{task_id}Query a single video task
GET/v2/query/video_generationList video tasks
DELETE/v2/video_generation/{task_id}Cancel or delete a task
POST/v1/files/uploadUpload a media file (multipart)
GET/v1/files/list?purpose=video_generation_inputList media files
GET/v1/files/retrieve?file_id={int64}Get file metadata and download URL
GET/v1/files/retrieve_content?file_id={int64}Get file content
POST/v1/files/deleteDelete a file

Create a video generation task

POST /v2/video_generation

Success response

Success returns HTTP 200 with a JSON body:

json
{"task_id":"1d6085ca-1d9a-4d61-a4a6-30e02079990f"}
FieldTypeDescription
task_idstringUUID of the new task; use it to query, cancel, or delete the task

Top-level fields

FieldContract
modelrequired; currently only MiniMax-H3
contentrequired non-empty array
resolutionrequired; currently only 768P
durationrequired integer; 4–15 seconds
ratioconditional rules below
callback_urloptional; status notifications are not currently supported
aigc_watermarkoptional boolean, default false; watermarks are not added during the current testing stage
context_ir_enabledEcoPhase extension; optional boolean, default true
The current capability supports 768P, 24 FPS, MP4/H.264, text-only generation, and first/last-frame video generation. context_ir_enabled controls Context IR prompt optimization and defaults to true, so prompt optimization is enabled unless explicitly disabled.

Create example

bash
curl -X POST "https://ecotoken.ecophase-ai.com/v2/video_generation" \
  -H "Authorization: Bearer ${VIDEO_API_KEY}" \
  -H "Idempotency-Key: video-create-001" \
  -H "Content-Type: application/json" \
  -d '{
    "model":"MiniMax-H3",
    "content":[{"type":"text","text":"a cinematic sunrise over an alpine lake"}],
    "resolution":"768P",
    "duration":5,
    "ratio":"16:9"
  }'

content

Every content item has a required type:

typeField that carries the value
texttext; exactly one non-empty prompt required, maximum 7,000 characters
image_urlimage_url.url
video_urlvideo_url.url
audio_urlaudio_url.url

Supported URL forms are public HTTP(S), mm_file://{file_id}, and strict Base64-encoded data:<media-type>;base64,<standard-base64> values. The entire JSON request body is at most 64 MiB. Upload large or reusable media first.

data:<media-type>;base64,<standard-base64> is a Data URL that embeds a small file directly in the JSON request, so it does not need to be uploaded first to obtain a public URL. - data: indicates that the value contains file data rather than a normal network address. - <media-type> is the file MIME type, such as image/png or audio/mpeg. - base64 is the fixed marker declaring Base64 encoding. - <standard-base64> is the original file encoded with standard Base64.

Roles are first_frame, last_frame, reference_image, reference_video, and reference_audio. A single image with no role defaults to first frame. Video and audio inputs use their corresponding reference roles.

Accepted scenes:

  • text only;
  • text + first frame;
  • text + last frame;
  • text + first and last frame;
  • text + any valid combination of reference images/videos/audio.

Frame roles and reference roles are mutually exclusive. First and last frame may each occur at most once.

Media validation

InputFormatPer-fileComplete request
imageJPG/JPEG, PNG, WebP, HEIC, HEIF≤30 MiB; width and height 256..5760 px; ratio 0.4..2.5first ≤1, last ≤1, reference images ≤9
videoMP4/MOV; H.264/AVC or H.265/HEVC; AAC/MP3 audio≤50 MiB; 2..15 s; dimensions 256..5760; ratio 0.4..2.5; FPS 23.976..60videos ≤3; sum of all video durations ≤15 s
audioPCM WAV/MP3≤15 MiB; 2..15 saudio files ≤3; sum of all audio durations ≤15 s

ratio

  • For T2VA, ratio is required and cannot be adaptive; it must be one of 21:9|16:9|4:3|1:1|3:4|9:16.
  • For I2VA, the ratio is derived from the input: an omitted value, adaptive, or another otherwise-valid ratio is normalized to adaptive.
  • For R2VA, the default is adaptive, and it can be changed to one of 21:9|16:9|4:3|1:1|3:4|9:16.

Query a single task

GET /v2/query/video_generation/{task_id}

Response format

json
{
  "task": {
    "id": "1d6085ca-1d9a-4d61-a4a6-30e02079990f",
    "model": "MiniMax-H3",
    "status": "succeeded",
    "created_at": 1787788800,
    "updated_at": 1787789100,
    "content": {"url": "https://SHORT_LIVED_DOWNLOAD_URL"},
    "resolution": "768P",
    "duration": 8,
    "usage": {"input_image_count": 1},
    "ratio": "adaptive",
    "task_type": "generation",
    "modality": "video"
  }
}

Task response fields

FieldTypeDescription
taskobjectVideo task object
task.idstringTask UUID
task.modelstringModel used to create the task
task.statusstringqueued, running, succeeded, failed, or cancelled
task.errorobject, optionalFailure details containing code and message; returned only on failure
task.created_atintegerCreation time as Unix seconds
task.updated_atintegerLast update time as Unix seconds
task.contentobject, optionalContains the short-lived output url after success
task.resolutionstring, optionalEffective resolution tier, such as 768P
task.durationintegerRequested video duration in seconds
task.usageobjectConfirmed usage; {} when no authoritative data exists, with absent counters treated as 0
task.ratiostringNormalized aspect ratio; usually adaptive for frame generation
task.task_typestringgeneration for current video tasks
task.modalitystringAlways video
task.internal_statusstring, optionalEcoPhase's precise processing phase: submitting, context_ir_queued, context_ir_running, video_generation_submitting, video_generation_running, or completed
task.phase_started_atinteger, optionalCurrent phase start time as Unix seconds
task.completed_atinteger, optionalCompletion time as Unix seconds
task.failed_phasestring, optionalFailure phase: context_ir or video_generation
task.context_irobject, optionalPrompt optimization result and usage, described below

Task status monitoring

We recommend using task.internal_status to monitor the precise processing phase. The MiniMax API field task.status does not distinguish every processing phase accurately.

Official MiniMax task.statusEcoPhase task.internal_statusDescription
queuedsubmittingThe request has been accepted and the task is being prepared
queuedcontext_ir_queuedThe Context IR prompt-optimization task is queued
runningcontext_ir_runningContext IR is optimizing the prompt
queuedvideo_generation_submittingThe task is being submitted to the video execution service
queued or runningvideo_generation_runningThe video task has been created; it is queued while waiting at the execution service and running after execution starts
succeeded, failed, or cancelledcompletedEcoPhase orchestration has ended; use task.status for the final outcome. Internal expiry also maps to official failed

task.context_ir fields:

FieldTypeDescription
enabledbooleanWhether Context IR was enabled for this task
statusstringsubmitting, queued, running, succeeded, failed, cancelled, or skipped
original_promptstringOriginal user prompt
optimized_promptstring, optionalOptimized prompt
usageobjectToken usage, possibly including prompt_tokens, completion_tokens, and total_tokens
started_atinteger, optionalOptimization start time as Unix seconds
completed_atinteger, optionalOptimization completion time as Unix seconds
errorobject, optionalOptimization failure containing code and message

Use task.content.url only after succeeded. The URL is short-lived and should not be persisted or cached for long periods.

task.context_ir reports enabled, status, original_prompt, optimized_prompt, token usage, started_at, completed_at, and an optional error. A Context IR failure fails the whole task and identifies failed_phase=context_ir.

Billing semantics

A video task is charged only when it succeeds:

  • Only a terminal status of `succeeded` is charged at all: priced on the measured output seconds times the resolution tier, plus this run's Context IR call (context_ir.status=succeeded, billed per call per task).
  • Any other terminal status (including `failed`, `cancelled`, and expiry) is free: output video, reference images, input audio/video, and the Context IR line are all waived. Prompt optimization is an intermediate step toward the video rather than a standalone deliverable, so no video means the whole pre-authorization is released.
  • A task is entirely free in two cases: the video generation failed or was cancelled, and the Context IR stage itself failed (no prompt delivered).
  • Retrying after a failure with a fresh idempotency key is therefore safe: a failure costs nothing. Resending with the same idempotency key does not re-execute the task and adds no charge (the original task is returned within 7 days).

List tasks

GET /v2/query/video_generation?page_num=&page_size=&filter.status=&filter.task_ids=&filter.model=

Tenant isolation is always applied. page_num defaults to 1; page_size defaults to 20 with a current maximum of 20. The list covers only tasks created in the most recent 7 days.

Query parameters support filter.status, filter.task_ids (repeat the parameter or use filter.task_ids[]; at most 100 lowercase canonical UUIDs), and filter.model. Response:

json
{
  "items": [
    {
      "id": "1d6085ca-1d9a-4d61-a4a6-30e02079990f",
      "model": "MiniMax-H3",
      "status": "succeeded",
      "created_at": 1787788800,
      "updated_at": 1787789100,
      "content": {"url": "https://SHORT_LIVED_DOWNLOAD_URL"},
      "resolution": "768P",
      "duration": 5,
      "usage": {},
      "ratio": "16:9",
      "task_type": "generation",
      "modality": "video"
    }
  ],
  "total": 1
}

total is the number of tasks matching the filters in the most recent 7 days.

FieldTypeDescription
itemsarrayTasks on the current page; each item has the same shape as task in the single-task response
totalintegerTotal matching tasks inside the recent 7-day window

Cancel or delete a task

DELETE /v2/video_generation/{task_id}

A queued task returns action=cancelled,status=cancelled only after cancellation is confirmed. While confirmation is pending, it remains queryable as queued and DELETE returns a retryable 503. If the first request used an Idempotency-Key, reuse that key when retrying. A running task cannot be cancelled and returns 400. A succeeded or failed terminal task can be logically removed from the compatibility list and returns action=deleted,status=deleted.

Success response body:

json
{
  "task_id": "1d6085ca-1d9a-4d61-a4a6-30e02079990f",
  "action": "cancelled",
  "status": "cancelled"
}

deleted describes the delete operation only; task.status in query responses never becomes deleted.

FieldTypeDescription
task_idstringUUID of the affected task
actionstringcancelled or deleted
statusstringcancelled or deleted, matching the operation result

File upload and media management

Media is referenced through public HTTP(S) URLs or managed files. Five operations are provided, all scoped to the authenticated user's media space. Different API keys and workspaces for one user share that space. Another user only receives not-found responses and cannot infer whether a file exists.

File-management JSON responses reuse these objects:

FieldTypeDescription
file.file_idintegerFile ID; reference it in video requests as mm_file://{file_id}
file.bytesintegerFile size in bytes
file.created_atintegerUpload time as Unix seconds
file.filenamestringOriginal upload filename
file.purposestringAlways video_generation_input
file.download_urlstring, optionalShort-lived download URL returned by file retrieval
base_resp.status_codeinteger0 indicates success
base_resp.status_msgstringsuccess on success

Upload

POST /v1/files/upload, using multipart/form-data. It must contain one purpose=video_generation_input field and one file part named file, with no other fields. The full request is limited to 64 MiB. Invalid media returns HTTP 400 and is not retained. Reference the result as mm_file://{file_id}. Files are retained for one day by default and can be deleted earlier.

bash
curl -X POST "https://ecotoken.ecophase-ai.com/v1/files/upload" \
  -H "Authorization: Bearer ${VIDEO_API_KEY}" \
  -H "Idempotency-Key: media-upload-001" \
  -F "purpose=video_generation_input" \
  -F "file=@./reference.mp4;type=video/mp4"

Success response:

json
{
  "file": {
    "file_id": 424010985738629,
    "bytes": 1234567,
    "created_at": 1788148800,
    "filename": "reference.mp4",
    "purpose": "video_generation_input"
  },
  "base_resp": {"status_code": 0, "status_msg": "success"}
}
FieldTypeDescription
fileobjectStored file object
base_respobjectMiniMax-compatible result; status_code=0 indicates success

List

GET /v1/files/list?purpose=video_generation_input

The success response contains all unexpired files owned by the current user:

json
{
  "files": [
    {
      "file_id": 424010985738629,
      "bytes": 1234567,
      "created_at": 1788148800,
      "filename": "reference.mp4",
      "purpose": "video_generation_input"
    }
  ],
  "base_resp": {"status_code": 0, "status_msg": "success"}
}
FieldTypeDescription
filesarrayUnexpired file objects owned by the current user; [] when empty
base_respobjectMiniMax-compatible result; status_code=0 indicates success

Retrieve a file

GET /v1/files/retrieve?file_id=424010985738629

json
{
  "file": {
    "file_id": 424010985738629,
    "bytes": 1234567,
    "created_at": 1788148800,
    "filename": "reference.mp4",
    "purpose": "video_generation_input",
    "download_url": "https://download.example/reference.mp4"
  },
  "base_resp": {"status_code": 0, "status_msg": "success"}
}
FieldTypeDescription
fileobjectFile metadata with an additional short-lived download_url
base_respobjectMiniMax-compatible result; status_code=0 indicates success

download_url is short-lived. Retrieve fresh metadata whenever a download is needed.

Download file content

GET /v1/files/retrieve_content?file_id=424010985738629

On success, the response body contains the file bytes with the corresponding Content-Type; it is not JSON. The client only sends its own EcoPhase API key.

Response headerDescription
Content-TypeActual file media type
Content-LengthFile size, when available

Delete

POST /v1/files/delete. The delete request uses purpose=video_generation; upload and list continue to use video_generation_input.

json
{"file_id":424010985738629,"purpose":"video_generation"}

Success response:

json
{
  "file_id": 424010985738629,
  "base_resp": {"status_code": 0, "status_msg": "success"}
}
FieldTypeDescription
file_idintegerID of the deleted file
base_respobjectMiniMax-compatible result; status_code=0 indicates success

Deleting the same file_id and purpose again as the same user is idempotent.

Error envelope

Video generation uses the MiniMax-compatible error envelope:

json
{
  "type": "error",
  "error": {"type": "bad_request_error", "message": "...", "http_code": "400"},
  "request_id": "..."
}
HTTPMeaning
400Invalid JSON, fields, multipart body, media constraints, query parameters, or task state; task/file missing, deleted, or owned by another user
401Missing, invalid, revoked, or insufficiently scoped API key
409An idempotency key conflicts with different content, or the same operation is still in progress
413The JSON request body exceeds the 64 MiB limit
422A synchronously detected content-policy rejection
429Identity rate limit or video execution capacity is temporarily exhausted; follow Retry-After
500Internal service error
503A dependency, current deployment capability, or cancellation confirmation is temporarily unavailable

Error response fields:

FieldTypeDescription
typestringAlways error
error.typestringError category such as bad_request_error, invalid_request_error, authorized_error, rate_limit_error, or server_error
error.messagestringHuman-readable error description suitable for display or logging
error.http_codestringHTTP status code represented as a string
request_idstringRequest trace ID to include when reporting a problem

Idempotency

Video generation, file upload, and task deletion support an optional Idempotency-Key. The value must contain 1–128 safe ASCII characters and is scoped to the current endpoint, service, workspace, and authenticated user. Rotating an API key for the same user does not change replay identity. A video-create key remains active for seven days after the first successful creation.

After an operation completes, the same key and request return the previous result. The same key with different content returns 409. An identical request may also receive 409 while the first operation is still in progress; retry later with exactly the same key and request. Deleting a task does not release its original create key. Reusing the key after the window expires creates a new task.

EcoPhase Docs - Video generation API reference - EcoPhase.AI