curl -X POST https://api.vibetool.ai/v1/videos/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "minimax-h3-image-to-video",
"image_urls": ["https://example.com/first-frame.png"],
"prompt": "the sailboat drifts toward the horizon as the sun sets",
"duration": 6
}'
import requests
url = "https://api.vibetool.ai/v1/videos/generations"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
payload = {
"model": "minimax-h3-image-to-video",
"image_urls": ["https://example.com/first-frame.png"],
"prompt": "the sailboat drifts toward the horizon as the sun sets",
"duration": 6
}
r = requests.post(url, json=payload, headers=headers, timeout=60)
print(r.status_code, r.json())
const response = await fetch("https://api.vibetool.ai/v1/videos/generations", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "minimax-h3-image-to-video",
image_urls: ["https://example.com/first-frame.png"],
prompt: "the sailboat drifts toward the horizon as the sun sets",
duration: 6
})
});
const data = await response.json();
console.log(data);
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
payload := map[string]interface{}{
"model": "minimax-h3-image-to-video",
"image_urls": []string{"https://example.com/first-frame.png"},
"prompt": "the sailboat drifts toward the horizon as the sun sets",
"duration": 6,
}
b, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "https://api.vibetool.ai/v1/videos/generations", bytes.NewReader(b))
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Println(result)
}
{
"id": "gen_vid_h3_002",
"object": "video.generation",
"model": "minimax-h3-image-to-video",
"created_at": 1786549095,
"status": "pending",
"task_id": "vid_202608130142_5e6f7a8b"
}
{
"error": {
"message": "Invalid image URL or unsupported image format.",
"type": "invalid_request_error",
"param": "image_urls",
"code": 400
}
}
Hailuo Series
Hailuo 3 Image To Video
MiniMax’s Hailuo 3 (MiniMax H3) animates still images into 2K video with first/last frame control, 4–15 second durations, and per-second billing via Vibetool’s asynchronous API.
POST
/
v1
/
videos
/
generations
curl -X POST https://api.vibetool.ai/v1/videos/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "minimax-h3-image-to-video",
"image_urls": ["https://example.com/first-frame.png"],
"prompt": "the sailboat drifts toward the horizon as the sun sets",
"duration": 6
}'
import requests
url = "https://api.vibetool.ai/v1/videos/generations"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
payload = {
"model": "minimax-h3-image-to-video",
"image_urls": ["https://example.com/first-frame.png"],
"prompt": "the sailboat drifts toward the horizon as the sun sets",
"duration": 6
}
r = requests.post(url, json=payload, headers=headers, timeout=60)
print(r.status_code, r.json())
const response = await fetch("https://api.vibetool.ai/v1/videos/generations", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "minimax-h3-image-to-video",
image_urls: ["https://example.com/first-frame.png"],
prompt: "the sailboat drifts toward the horizon as the sun sets",
duration: 6
})
});
const data = await response.json();
console.log(data);
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
payload := map[string]interface{}{
"model": "minimax-h3-image-to-video",
"image_urls": []string{"https://example.com/first-frame.png"},
"prompt": "the sailboat drifts toward the horizon as the sun sets",
"duration": 6,
}
b, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "https://api.vibetool.ai/v1/videos/generations", bytes.NewReader(b))
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Println(result)
}
{
"id": "gen_vid_h3_002",
"object": "video.generation",
"model": "minimax-h3-image-to-video",
"created_at": 1786549095,
"status": "pending",
"task_id": "vid_202608130142_5e6f7a8b"
}
{
"error": {
"message": "Invalid image URL or unsupported image format.",
"type": "invalid_request_error",
"param": "image_urls",
"code": 400
}
}
Pricing: See vibetool.ai/pricing for current rates.
Input Modalities
- Image – a first-frame image, and optionally a last-frame image, passed via
image_urls - Text – (optional) a prompt describing the desired motion, scene evolution, and style
Output Modality
- Video – a 2K MP4 file, 4–15 seconds long
Authorization
string
required
All APIs require Bearer Token authentication. Format:
Bearer YOUR_API_KEYRequest Body
string
required
The model identifier. Use
"minimax-h3-image-to-video".array of strings
required
Publicly accessible image URLs. The first URL is used as the video’s first frame; an optional second URL is used as the last frame for first/last-frame interpolation.
string
Optional text description of the desired motion and scene evolution (e.g., “the camera slowly pulls back as snow begins to fall”).
integer
default:"4"
Video duration in seconds — any integer from 4 to 15. Defaults to 4 when omitted.
Hailuo 3 generates one video per request — the
n parameter is not supported.
Output resolution is fixed at 2K.Response Schema
string
required
Unique identifier for the generation task.
string
required
Type of object, always
"video.generation".string
required
The model used, e.g.,
"minimax-h3-image-to-video".integer
required
Unix timestamp (seconds) of task creation.
string
required
Initial status:
"pending" or "processing". Use the Get Video Status endpoint to poll for completion.string
required
The task ID to query in the status endpoint.
curl -X POST https://api.vibetool.ai/v1/videos/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "minimax-h3-image-to-video",
"image_urls": ["https://example.com/first-frame.png"],
"prompt": "the sailboat drifts toward the horizon as the sun sets",
"duration": 6
}'
import requests
url = "https://api.vibetool.ai/v1/videos/generations"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
payload = {
"model": "minimax-h3-image-to-video",
"image_urls": ["https://example.com/first-frame.png"],
"prompt": "the sailboat drifts toward the horizon as the sun sets",
"duration": 6
}
r = requests.post(url, json=payload, headers=headers, timeout=60)
print(r.status_code, r.json())
const response = await fetch("https://api.vibetool.ai/v1/videos/generations", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "minimax-h3-image-to-video",
image_urls: ["https://example.com/first-frame.png"],
prompt: "the sailboat drifts toward the horizon as the sun sets",
duration: 6
})
});
const data = await response.json();
console.log(data);
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
payload := map[string]interface{}{
"model": "minimax-h3-image-to-video",
"image_urls": []string{"https://example.com/first-frame.png"},
"prompt": "the sailboat drifts toward the horizon as the sun sets",
"duration": 6,
}
b, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "https://api.vibetool.ai/v1/videos/generations", bytes.NewReader(b))
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
fmt.Println(result)
}
{
"id": "gen_vid_h3_002",
"object": "video.generation",
"model": "minimax-h3-image-to-video",
"created_at": 1786549095,
"status": "pending",
"task_id": "vid_202608130142_5e6f7a8b"
}
{
"error": {
"message": "Invalid image URL or unsupported image format.",
"type": "invalid_request_error",
"param": "image_urls",
"code": 400
}
}
task_id until status is "completed" and the generated video URL is available.Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
application/json
Use minimax-h3-image-to-video.
Available options:
minimax-h3-image-to-video First frame, optionally last frame
Maximum array length:
2Text description of the video to generate
Duration in seconds (4-15)
Required range:
4 <= x <= 15Was this page helpful?