curl --request POST \
--url https://api.goenhance.ai/api/v1/videos/generations \
--header 'Content-Type: application/json' \
--data '
{
"model": "minimax-h3-swap",
"image_url": "https://cdn.goenhance.ai/user/goenhance/76115ad445ce26fbd5ad2c649a29e806.jpg",
"video_url": "https://cdn.goenhance.ai/user/upload-data/video-to-video/333768e610e442d02e8030693def0b6e.mp4",
"swap_target": "the person in the center of the frame"
}
'import requests
url = "https://api.goenhance.ai/api/v1/videos/generations"
payload = {
"model": "minimax-h3-swap",
"image_url": "https://cdn.goenhance.ai/user/goenhance/76115ad445ce26fbd5ad2c649a29e806.jpg",
"video_url": "https://cdn.goenhance.ai/user/upload-data/video-to-video/333768e610e442d02e8030693def0b6e.mp4",
"swap_target": "the person in the center of the frame"
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'minimax-h3-swap',
image_url: 'https://cdn.goenhance.ai/user/goenhance/76115ad445ce26fbd5ad2c649a29e806.jpg',
video_url: 'https://cdn.goenhance.ai/user/upload-data/video-to-video/333768e610e442d02e8030693def0b6e.mp4',
swap_target: 'the person in the center of the frame'
})
};
fetch('https://api.goenhance.ai/api/v1/videos/generations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.goenhance.ai/api/v1/videos/generations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'minimax-h3-swap',
'image_url' => 'https://cdn.goenhance.ai/user/goenhance/76115ad445ce26fbd5ad2c649a29e806.jpg',
'video_url' => 'https://cdn.goenhance.ai/user/upload-data/video-to-video/333768e610e442d02e8030693def0b6e.mp4',
'swap_target' => 'the person in the center of the frame'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.goenhance.ai/api/v1/videos/generations"
payload := strings.NewReader("{\n \"model\": \"minimax-h3-swap\",\n \"image_url\": \"https://cdn.goenhance.ai/user/goenhance/76115ad445ce26fbd5ad2c649a29e806.jpg\",\n \"video_url\": \"https://cdn.goenhance.ai/user/upload-data/video-to-video/333768e610e442d02e8030693def0b6e.mp4\",\n \"swap_target\": \"the person in the center of the frame\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.goenhance.ai/api/v1/videos/generations")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"minimax-h3-swap\",\n \"image_url\": \"https://cdn.goenhance.ai/user/goenhance/76115ad445ce26fbd5ad2c649a29e806.jpg\",\n \"video_url\": \"https://cdn.goenhance.ai/user/upload-data/video-to-video/333768e610e442d02e8030693def0b6e.mp4\",\n \"swap_target\": \"the person in the center of the frame\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.goenhance.ai/api/v1/videos/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"minimax-h3-swap\",\n \"image_url\": \"https://cdn.goenhance.ai/user/goenhance/76115ad445ce26fbd5ad2c649a29e806.jpg\",\n \"video_url\": \"https://cdn.goenhance.ai/user/upload-data/video-to-video/333768e610e442d02e8030693def0b6e.mp4\",\n \"swap_target\": \"the person in the center of the frame\"\n}"
response = http.request(request)
puts response.read_body{
"code": 0,
"msg": "Success",
"data": {
"img_uuid": "c12b656c-747a-44fd-9c80-add79b0c52d5",
"cost": 28
}
}MiniMax-H3 Character Replace
Replace the main person in a guide video with the person from your photo — face, hair, body and outfit. The original scene, camera motion, movement and audio track are kept.
By default the output follows the guide video’s length, rounded down to whole seconds (a 14.6-second video gives a 14-second result). The guide video must be at least 5 seconds long; videos longer than 15 seconds are rejected unless you pass duration, which renders only their first N seconds. The aspect ratio follows the guide video.
If you don’t pass swap_details, the photo is described automatically and that description is used to transfer the outfit. In videos with several people, use swap_target to say which one to replace.
Tips — a clear, front-facing half-body or full-body photo of a single person works best. Everything else in the frame is kept as-is, including any logos, watermarks or text in the original video.
Pricing — per second of generated video, in tokens (USD at $0.02/token):
| resolution | tokens/s | USD/s | per 5s |
|---|---|---|---|
| 720p | 2 | $0.04 | $0.20 |
Returns an img_uuid; poll GET /api/v1/jobs/detail (or use custom_callback_url) to get the generated video.
curl --request POST \
--url https://api.goenhance.ai/api/v1/videos/generations \
--header 'Content-Type: application/json' \
--data '
{
"model": "minimax-h3-swap",
"image_url": "https://cdn.goenhance.ai/user/goenhance/76115ad445ce26fbd5ad2c649a29e806.jpg",
"video_url": "https://cdn.goenhance.ai/user/upload-data/video-to-video/333768e610e442d02e8030693def0b6e.mp4",
"swap_target": "the person in the center of the frame"
}
'import requests
url = "https://api.goenhance.ai/api/v1/videos/generations"
payload = {
"model": "minimax-h3-swap",
"image_url": "https://cdn.goenhance.ai/user/goenhance/76115ad445ce26fbd5ad2c649a29e806.jpg",
"video_url": "https://cdn.goenhance.ai/user/upload-data/video-to-video/333768e610e442d02e8030693def0b6e.mp4",
"swap_target": "the person in the center of the frame"
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'minimax-h3-swap',
image_url: 'https://cdn.goenhance.ai/user/goenhance/76115ad445ce26fbd5ad2c649a29e806.jpg',
video_url: 'https://cdn.goenhance.ai/user/upload-data/video-to-video/333768e610e442d02e8030693def0b6e.mp4',
swap_target: 'the person in the center of the frame'
})
};
fetch('https://api.goenhance.ai/api/v1/videos/generations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.goenhance.ai/api/v1/videos/generations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => 'minimax-h3-swap',
'image_url' => 'https://cdn.goenhance.ai/user/goenhance/76115ad445ce26fbd5ad2c649a29e806.jpg',
'video_url' => 'https://cdn.goenhance.ai/user/upload-data/video-to-video/333768e610e442d02e8030693def0b6e.mp4',
'swap_target' => 'the person in the center of the frame'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.goenhance.ai/api/v1/videos/generations"
payload := strings.NewReader("{\n \"model\": \"minimax-h3-swap\",\n \"image_url\": \"https://cdn.goenhance.ai/user/goenhance/76115ad445ce26fbd5ad2c649a29e806.jpg\",\n \"video_url\": \"https://cdn.goenhance.ai/user/upload-data/video-to-video/333768e610e442d02e8030693def0b6e.mp4\",\n \"swap_target\": \"the person in the center of the frame\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.goenhance.ai/api/v1/videos/generations")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"minimax-h3-swap\",\n \"image_url\": \"https://cdn.goenhance.ai/user/goenhance/76115ad445ce26fbd5ad2c649a29e806.jpg\",\n \"video_url\": \"https://cdn.goenhance.ai/user/upload-data/video-to-video/333768e610e442d02e8030693def0b6e.mp4\",\n \"swap_target\": \"the person in the center of the frame\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.goenhance.ai/api/v1/videos/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"minimax-h3-swap\",\n \"image_url\": \"https://cdn.goenhance.ai/user/goenhance/76115ad445ce26fbd5ad2c649a29e806.jpg\",\n \"video_url\": \"https://cdn.goenhance.ai/user/upload-data/video-to-video/333768e610e442d02e8030693def0b6e.mp4\",\n \"swap_target\": \"the person in the center of the frame\"\n}"
response = http.request(request)
puts response.read_body{
"code": 0,
"msg": "Success",
"data": {
"img_uuid": "c12b656c-747a-44fd-9c80-add79b0c52d5",
"cost": 28
}
}Headers
Body
Model name. Must be minimax-h3-swap.
minimax-h3-swap Publicly accessible URL of the person photo (max 10 MB). This person replaces the main person in the video. A clear, front-facing half-body or full-body photo of a single person works best.
Publicly accessible URL of the guide video (max 100 MB, at least 5 seconds). Its main person is replaced; the scene, camera motion, movement and audio are kept. Videos longer than 15 seconds are rejected unless you pass duration.
Optional. Render only the first N seconds of the guide video (5–15). Omit it to follow the video's length, rounded down to whole seconds. Must not exceed the actual video length — a longer value is rejected rather than silently clamped. Billing follows the output length.
5 <= x <= 15Optional. Accepted values are 480p and 720p; the video is always generated at 720p, at the same price. The aspect ratio follows the guide video.
480p, 720p Optional. In videos with several people, which person to replace. Describe them by position or action (for example "the man on the left" or "the player kicking the ball"), not by clothing. Longer text is truncated to 600 characters.
600Optional. An appearance description of the person in the photo, head to toe (for example "East Asian woman, long black hair, white T-shirt, blue jeans, white sneakers"). If omitted, the photo is described automatically. Longer text is truncated to 800 characters.
800Optional. A publicly accessible HTTPS URL. When the task status changes (processing / success / failed), GoEnhance sends a POST request to this URL. The request body is identical to the response of GET /api/v1/jobs/detail. If your server does not respond with HTTP 200, the notification is retried up to 3 times, with a 3-second timeout per attempt.
"https://your-server.com/goenhance/callback"
