Skip to main content
POST
Generate a video from text, or from a first and optional last frame
Send multipart/form-data with both a first frame and a last frame, each independently as an uploaded file or a URL. Supplying both is what selects this mode of POST /v1/videos — a last frame is only valid alongside a first frame. Generates a Viggle-optimized MiniMax H3 video with native audio. This uses the same POST /v1/videos endpoint as Generate Video (from Text) and Generate Video (from First Frame and/or Text) — which mode runs is selected by which frame fields you send, not by a separate parameter.
Every generated video includes native audio — there’s no separate audio flag or field. Pricing (1 credit = 0.01):durations×thepersecondrateforquality0.01): ⌈`duration_s`⌉ × the per-second rate for `quality` — **0.01/sec (1 credit/second)** for both low and high. Image-conditioned generation costs the same as text-only for the same quality and duration; resolution and aspect_ratio don’t affect price. See Pricing and retention.

Request parameters

Send multipart/form-data. Provide exactly one of first_frame_image/first_frame_image_url, and exactly one of last_frame_image/last_frame_image_url. Supplying both forms of the same slot answers 400 INVALID_REQUEST — “supply only one of first_frame_image or first_frame_image_url” (or the last_frame_* equivalent). Supplying a last frame with no first frame answers 400 INVALID_REQUEST — “a last frame requires a first frame”.

Response parameters

Returns 200 OK — an acceptance acknowledgment, not the final result.
This response deliberately carries none of the fields GET /v1/videos/{video_id} returns (stage, video_url, alpha_url, completed_at, error). See Get Video for the full shape once the video is processing or done.

Examples

Common errors

Next step

Use Get Video with the returned id to poll for the result.

Quick Start: First-Last Frames to Video

Follow the complete create-and-poll flow.

Generate Video (from Text)

Generate from a prompt alone, with no frame image.

Generate Video (from First Frame and/or Text)

Anchor only the start of the video, with no last frame.

Authorizations

Authorization
string
header
required

Server-side SDK clients use a project API key. Remote MCP clients use an OAuth access token. Never expose a project API key in browser code.

Headers

X-Request-Id
string

Optional caller-supplied correlation ID, up to 128 characters. The service returns the effective value in the response header for tracing and support.

Required string length: 1 - 128
X-Viggle-Source
string

Optional source-channel label, up to 128 characters, used to attribute traffic to an SDK, integration, product surface, or internal workflow.

Required string length: 1 - 128

Body

multipart/form-data

Body of POST /v1/videos, multipart/form-data only. Which frame fields are supplied selects the generation mode:

  • Neither first_frame_image/first_frame_image_url nor last_frame_image/last_frame_image_url supplied: text-to-video.
  • A first frame supplied, no last frame: first-frame-to-video.
  • Both a first frame and a last frame supplied: first+last-frame-to-video.

Within a frame slot, supply at most one of the file and the URL form. Supplying both first_frame_image and first_frame_image_url (or both last_frame_image and last_frame_image_url) answers 400 INVALID_REQUEST with "supply only one of first_frame_image or first_frame_image_url" (or the last_frame_* equivalent). A last frame requires a first frame; supplying a last frame with no first frame answers 400 INVALID_REQUEST with "a last frame requires a first frame".

Billed at ⌈duration_s⌉ × the per-second credit rate for quality (currently 1 credit/second — $0.01/sec — for both low and high). resolution and aspect_ratio do not affect price, and image-conditioned generation (first-frame or first-last-frame) costs the same as text-only for the same quality and duration.

Every generated video includes native audio; there is no separate audio flag or field.

prompt
string
required

Text description of the desired video. Required and non-empty in every mode, including first-frame and first+last-frame modes.

Minimum string length: 1
Example:

"A paper airplane gliding through a sunlit office"

quality
enum<string>
required

Generation quality tier — also selects the per-second credit rate charged for this request. low generates faster, for quicker iteration; high generates slower but produces higher-fidelity output. Both tiers are billed at the same $0.01/sec rate.

Available options:
low,
high
Example:

"low"

first_frame_image
file

First-frame image uploaded directly. Mutually exclusive with first_frame_image_url. Supplying either switches on first-frame-to-video mode.

first_frame_image_url
string<uri>

Publicly reachable URL of the first-frame image; the service fetches and re-hosts it. Mutually exclusive with first_frame_image.

last_frame_image
file

Last-frame image uploaded directly. Mutually exclusive with last_frame_image_url. Valid only alongside a first frame.

last_frame_image_url
string<uri>

Publicly reachable URL of the last-frame image; the service fetches and re-hosts it. Mutually exclusive with last_frame_image. Valid only alongside a first frame.

duration_s
number
default:5

Target video duration in seconds.

Required range: 3 <= x <= 15
resolution
enum<string>
default:768p

Output resolution tier.

Available options:
480p,
768p,
1080p
aspect_ratio
enum<string>
default:16:9

Output aspect ratio.

Available options:
16:9,
9:16,
1:1,
4:3,
3:4,
21:9
seed
integer

Deterministic generation seed. Omit for a random seed.

Required range: x >= 0
watermark
boolean
default:false

Whether to burn in a Viggle watermark.

Response

Video generation accepted and queued.

Acceptance acknowledgment for POST /v1/videos, shared by all three generation modes. This is a queued confirmation, not the final result — poll GET /v1/videos/{video_id} (or watch it via GET /v1/videos) until status reaches ready, then read video_url from that response.

id
string
required

Public video ID, vid_-prefixed.

Minimum string length: 1
status
enum<string>
required

Lifecycle state at acceptance time; always queued.

Available options:
queued,
processing,
ready,
failed,
cancelled
progress
integer | null
required

Always null on acceptance.

Required range: 0 <= x <= 100
created_at
string<date-time> | null
required

ISO 8601 creation timestamp, second precision.