FaceDetect
namifusion/detect_faces
A face detection model used to detect facial information contained in input elements.
Examples
Parameters
| Name | Type | Default | Constraints | Description |
|---|---|---|---|---|
| urlMedia URL | text | — | — | Image or video URL. At least one of url or img is required. url has higher priority when both are provided. |
| imgBase64 Image | textarea | — | — | Base64-encoded image input (used when url is not provided). |
| num_framesNumber of Frames | number | 5 | — | Number of frames to sample from video input. |
| return_face_urlReturn Face URL | boolean | true | — | Whether to return cropped face image URLs. |
| single_faceSingle Face Only | boolean | false | — | Whether to return only the largest detected face. |
| deduplicateDeduplicate Faces | boolean | true | — | Whether to deduplicate faces across sampled video frames. |
| similarity_thresholdSimilarity Threshold | number | 0.45 | — | Deduplication similarity threshold (0.0-1.0); higher means stricter. |
| time_rangeTime Range | object | {} | — | Optional video processing range in seconds; only effective for video input. |
| ↳startStart | number | — | ≥ 0 | |
| ↳endEnd | number | — | ≥ 0 |
API
Call this model through one unified REST API. Get a key on the API Keys page.
cURL
# 1) Submit — returns { "task_uuid": "..." }
curl -X POST "https://www.namifusion.com/api/v1/marketplace/run/namifusion/detect_faces" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": {
"url": "https://assets-public.namifusion.com/marketplace/thumbnails/2026-02-25/fb559d5bc3dc.png",
"num_frames": 5,
"return_face_url": true,
"single_face": false,
"deduplicate": true,
"similarity_threshold": 0.45,
"time_range": {}
}
}'
# 2) Poll until status is "completed", then read the output URLs
curl "https://www.namifusion.com/api/v1/marketplace/run/tasks/TASK_UUID" \
-H "Authorization: Bearer YOUR_API_KEY"Python
import time, requests
API_KEY = "YOUR_API_KEY"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# 1) Submit
resp = requests.post(
"https://www.namifusion.com/api/v1/marketplace/run/namifusion/detect_faces",
headers=HEADERS,
json={
"input": {
"url": "https://assets-public.namifusion.com/marketplace/thumbnails/2026-02-25/fb559d5bc3dc.png",
"num_frames": 5,
"return_face_url": True,
"single_face": False,
"deduplicate": True,
"similarity_threshold": 0.45,
"time_range": {}
}
},
)
resp.raise_for_status() # 401/402/429/5xx stop here instead of polling a bad task
task = resp.json()
# 2) Poll until a terminal state (completed / failed / cancelled).
# This model is allowed up to 30s server-side.
deadline = time.time() + 90
while task.get("status") not in ("completed", "failed", "cancelled"):
if time.time() > deadline:
raise TimeoutError(f"still {task.get('status')} — keep the task_uuid and poll later")
time.sleep(3)
poll = requests.get(f"https://www.namifusion.com/api/v1/marketplace/run/tasks/{task['task_uuid']}", headers=HEADERS)
poll.raise_for_status()
task = poll.json()
print(task["status"], task.get("output"))JavaScript
const API_KEY = "YOUR_API_KEY";
const HEADERS = { Authorization: `Bearer ${API_KEY}` };
// 1) Submit
const resp = await fetch("https://www.namifusion.com/api/v1/marketplace/run/namifusion/detect_faces", {
method: "POST",
headers: { ...HEADERS, "Content-Type": "application/json" },
body: JSON.stringify({
"input": {
"url": "https://assets-public.namifusion.com/marketplace/thumbnails/2026-02-25/fb559d5bc3dc.png",
"num_frames": 5,
"return_face_url": true,
"single_face": false,
"deduplicate": true,
"similarity_threshold": 0.45,
"time_range": {}
}
}),
});
if (!resp.ok) throw new Error(`submit failed: ${resp.status} ${await resp.text()}`);
let task = await resp.json();
// 2) Poll until a terminal state (completed / failed / cancelled).
// This model is allowed up to 30s server-side.
const deadline = Date.now() + 90 * 1000;
while (!["completed", "failed", "cancelled"].includes(task.status)) {
if (Date.now() > deadline) throw new Error(`still ${task.status} — keep the task_uuid and poll later`);
await new Promise((r) => setTimeout(r, 3000));
const poll = await fetch(`https://www.namifusion.com/api/v1/marketplace/run/tasks/${task.task_uuid}`, { headers: HEADERS });
if (!poll.ok) throw new Error(`poll failed: ${poll.status}`);
task = await poll.json();
}
console.log(task.status, task.output);Documentation
NamiFusion Video FaceSwap
AI Video Face Swap: Supports single-person automatic face swap and multi-person precise mapping, combined with face detection for a complete video face swap workflow.
NamiFusion Video FaceSwap is a high-quality AI video face swap service that replaces source faces onto target videos. It offers two modes: single-person face swap (automatic mode) and multi-person face swap (precise mapping mode), and can be combined with NamiFusion Detect Faces to achieve a complete workflow from face detection to face swapping.
Key Features
- Single-Person Face Swap: Enable
single_face_modeto automatically complete the face swap without any additional configuration. - Multi-Person Precise Mapping: Use
face_mappingto precisely specify the correspondence between source faces and target faces, supporting one-to-one and many-to-many mappings. - Face Enhancement: Optional advanced beautification that automatically smooths skin and removes facial blemishes, improving post-swap face quality.
- Async Tasks: Returns a
task_uuidafter submission; retrieve results via polling or Webhook.
Technical Specifications
| Parameter | Details |
|---|---|
| Model ID | namifusion/faceswap-video |
| Request Method | Async POST (submit task + poll/Webhook for results) |
| Input | Source face image URL + target video URL |
| Output | Face-swapped video URL |
| Processing Time | Typically 30 seconds to several minutes (depends on video duration and resolution) |
| Source Image Formats | JPG, PNG; resolution up to 4K |
| Target Video Formats | MP4, MOV, WEBM, AVI; max file size 5 GB; max duration 2 hours; resolution up to 4K |
Quick Start
API Endpoints
| Endpoint | Method | Description |
|---|---|---|
/api/v1/marketplace/run/namifusion/faceswap-video | POST | Submit a video face swap task |
/api/v1/marketplace/run/tasks/{task_uuid} | GET | Query task status and results |
Authentication
Include your API Key in the request header:
X-API-Key: sk-your-api-key
Scenario 1: Single-Person Face Swap (Simplest Usage)
Suitable for scenarios where the source image and target video both contain only one face. With single_face_mode enabled, no face_mapping configuration is needed, and the service will automatically complete the face swap.
Step 1: Submit Face Swap Task
curl -X POST "https://www.namifusion.com/api/v1/marketplace/run/namifusion/faceswap-video" \
-H "X-API-Key: sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"input": {
"source_url": "https://example.com/source_face.jpg",
"target_url": "https://example.com/target_video.mp4",
"single_face_mode": true
}
}'
Response Example:
{
"task_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "pending",
"cost_credits": 50
}
Step 2: Poll Task Status
curl -X GET "https://www.namifusion.com/api/v1/marketplace/run/tasks/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-H "X-API-Key: sk-your-api-key"
Processing:
{
"task_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "processing"
}
Completed:
{
"task_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"model_id": "namifusion/faceswap-video",
"status": "completed",
"output": {
"videos": ["https://cdn.namifusion.com/result/faceswap_abc123.mp4"]
},
"cost_credits": 50,
"created_at": "2026-02-27T10:00:00Z",
"completed_at": "2026-02-27T10:01:30Z"
}
Scenario 2: Multi-Person Face Swap
When the target video contains multiple faces and you need precise control over "which source face replaces which target face", you need to first call Detect Faces to detect faces from the video, then build face_mapping to submit the face swap task.
Step 1: Detect Faces in the Target Video
Call NamiFusion Detect Faces (POST /api/v1/marketplace/run/namifusion/detect_faces) to detect faces directly from the video, then poll for results.
Submit Detection Task:
curl -X POST "https://www.namifusion.com/api/v1/marketplace/run/namifusion/detect_faces" \
-H "X-API-Key: sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"input": {
"url": "https://example.com/target_video.mp4",
"num_frames": 3,
"return_face_url": true,
"deduplicate": true
}
}'
num_framesspecifies how many frames to uniformly sample from the video for face detection. Maximum value: 100. A higher value improves the chance of detecting all faces but increases processing time. For most videos, 3–10 frames is sufficient.
Poll Task Result:
curl -X GET "https://www.namifusion.com/api/v1/marketplace/run/tasks/{task_uuid}" \
-H "X-API-Key: sk-your-api-key"
Completed Response (assuming 2 persons detected):
{
"task_uuid": "...",
"status": "completed",
"output": {
"error_code": 0,
"error_msg": "SUCCESS",
"faces_obj": {
"0": {
"region": [[50, 80, 150, 200], [250, 70, 350, 190]],
"face_urls": [
"https://s3.amazonaws.com/faces/target_face_0.jpg",
"https://s3.amazonaws.com/faces/target_face_1.jpg"
],
"landmarks": [[[...]], [[...]]],
"frame_time": null,
"crop_region": [[...], [...]],
"landmarks_str": ["...", "..."],
"crop_landmarks": ["...", "..."]
},
"1": {
"region": [],
"face_urls": [],
"landmarks": [],
"frame_time": 1.0,
"crop_region": [],
"landmarks_str": [],
"crop_landmarks": []
},
"2": {
"region": [],
"face_urls": [],
"landmarks": [],
"frame_time": 2.0,
"crop_region": [],
"landmarks_str": [],
"crop_landmarks": []
}
}
}
}
Now you know the target video has 2 persons (faces_obj["0"].region length is 2) and their face_urls.
Step 2: Detect Source Face Image
Similarly, call Detect Faces to submit a detection task and poll for results (if you have multiple source face images or need to pass precise face coordinate information).
Submit Detection Task:
curl -X POST "https://www.namifusion.com/api/v1/marketplace/run/namifusion/detect_faces" \
-H "X-API-Key: sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"input": {
"url": "https://example.com/source_face.jpg",
"return_face_url": true
}
}'
Completed Response:
{
"task_uuid": "...",
"status": "completed",
"output": {
"error_code": 0,
"error_msg": "SUCCESS",
"faces_obj": {
"0": {
"region": [[100, 50, 200, 180]],
"face_urls": ["https://s3.amazonaws.com/faces/source_face_0.jpg"],
"landmarks": [[[...]]],
"frame_time": null,
"crop_region": [[...]],
"landmarks_str": ["..."],
"crop_landmarks": ["..."]
}
}
}
}
Step 3: Build face_mapping
Based on the detection results, build the mapping from source faces to target faces.
Use the face_urls returned by Detect Faces as source_face_info.face_url and target_face_info.face_url in face_mapping:
"face_mapping": [
{
"source_face_info": {
"face_url": "https://s3.amazonaws.com/faces/source_face_0.jpg"
},
"target_face_info": {
"face_url": "https://s3.amazonaws.com/faces/target_face_0.jpg"
}
}
]
The face_url values are taken directly from the output.faces_obj["0"].face_urls[i] returned by Detect Faces in Steps 1 and 2.
face_mappingalso supportssource_face_index,target_face_index,bbox, and other parameters. See the "face_mapping Details" section below.
Step 4: Submit Multi-Person Face Swap Task
curl -X POST "https://www.namifusion.com/api/v1/marketplace/run/namifusion/faceswap-video" \
-H "X-API-Key: sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"input": {
"source_url": "https://example.com/source_face.jpg",
"target_url": "https://example.com/target_video.mp4",
"single_face_mode": false,
"face_mapping": [
{
"source_face_info": {
"face_url": "https://s3.amazonaws.com/faces/source_face_0.jpg"
},
"target_face_info": {
"face_url": "https://s3.amazonaws.com/faces/target_face_0.jpg"
}
}
]
}
}'
Response:
{
"task_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"status": "pending",
"cost_credits": 50
}
Step 5: Get Face Swap Result
Poll the task status until status becomes completed:
curl -X GET "https://www.namifusion.com/api/v1/marketplace/run/tasks/b2c3d4e5-f6a7-8901-bcde-f12345678901" \
-H "X-API-Key: sk-your-api-key"
Completed Response:
{
"task_uuid": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"model_id": "namifusion/faceswap-video",
"status": "completed",
"output": {
"videos": ["https://cdn.namifusion.com/result/faceswap_def456.mp4"]
},
"cost_credits": 50,
"created_at": "2026-02-27T10:05:00Z",
"completed_at": "2026-02-27T10:07:30Z"
}
Python Full Example: Multi-Person Video Face Swap Workflow
The following example demonstrates the complete workflow from face detection to multi-person video face swap:
import requests
import time
API_KEY = "sk-your-api-key"
BASE_URL = "https://www.namifusion.com/api/v1/marketplace/run"
HEADERS = {
"X-API-Key": API_KEY,
"Content-Type": "application/json",
}
source_url = "https://example.com/source_face.jpg"
target_url = "https://example.com/target_video.mp4"
def detect_faces(media_url, num_frames=None):
"""Submit face detection task and poll for result."""
input_params = {"url": media_url, "return_face_url": True}
if num_frames:
input_params["num_frames"] = num_frames
task = requests.post(
f"{BASE_URL}/namifusion/detect_faces",
headers=HEADERS,
json={"input": input_params},
).json()
while True:
resp = requests.get(
f"{BASE_URL}/tasks/{task['task_uuid']}",
headers=HEADERS,
).json()
if resp["status"] == "completed":
return resp["output"]
elif resp["status"] == "failed":
raise Exception(resp.get("error_message", "Unknown error"))
time.sleep(3)
# Step 1: detect faces in target video
target_detect = detect_faces(target_url, num_frames=3)
target_frame = target_detect["faces_obj"]["0"]
print(f"Target has {len(target_frame['face_urls'])} faces")
for i, face_url in enumerate(target_frame["face_urls"]):
print(f" Face {i}: region={target_frame['region'][i]}")
# Step 2: detect faces in source image
source_detect = detect_faces(source_url)
source_frame = source_detect["faces_obj"]["0"]
# Step 3: build face_mapping (replace target face 0 with source face 0)
face_mapping = [
{
"source_face_info": {"face_url": source_frame["face_urls"][0]},
"target_face_info": {"face_url": target_frame["face_urls"][0]},
}
]
# Step 4: submit video faceswap task
task_resp = requests.post(
f"{BASE_URL}/namifusion/faceswap-video",
headers=HEADERS,
json={
"input": {
"source_url": source_url,
"target_url": target_url,
"single_face_mode": False,
"face_mapping": face_mapping,
}
},
).json()
task_uuid = task_resp["task_uuid"]
print(f"Task submitted: {task_uuid}")
# Step 5: poll for result
while True:
status_resp = requests.get(
f"{BASE_URL}/tasks/{task_uuid}",
headers=HEADERS,
).json()
status = status_resp["status"]
print(f"Status: {status}")
if status == "completed":
result_url = status_resp["output"]["videos"][0]
print(f"Result: {result_url}")
break
elif status == "failed":
print(f"Failed: {status_resp.get('error_message', 'Unknown error')}")
break
time.sleep(10)
Parameter and Response Details
Request Parameters
The request body is in JSON format, with all parameters inside the input object:
{
"input": {
"source_url": "https://...",
"target_url": "https://...",
"single_face_mode": true,
"face_enhance": false,
"face_mapping": [],
"model_style": "realistic"
}
}
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
source_url | string | Yes | - | Source face image URL (the face to swap onto the target). Must be publicly accessible. Supports HTTP/HTTPS. Supported formats: JPG, PNG. Resolution up to 4K. |
target_url | string | Yes | - | Target video URL (the video to be face-swapped). Must be publicly accessible. Supports HTTP/HTTPS. Supported formats: MP4, MOV, WEBM, AVI. Max file size 5 GB, max duration 2 hours, resolution up to 4K. |
single_face_mode | boolean | No | true | Single face mode. When enabled, face swap is completed automatically without configuring face_mapping. |
face_enhance | boolean | No | false | Whether to enable face enhancement. When enabled, automatically smooths skin and removes facial blemishes for higher face quality, but increases processing time. |
face_mapping | array | No | null | Face mapping configuration. Only effective when single_face_mode: false. See details below. |
model_style | string | No | "realistic" | Face swap style. Options: "realistic", "beautify", "lossless". See the "Impact of Parameters on Output" section. |
face_mapping Details
face_mapping is an array where each element defines a mapping from a source face to a target face:
| Field | Type | Required | Description |
|---|---|---|---|
source_face_index | integer | Yes | Index of the face in the source image (0-based, sorted left to right). |
target_face_index | integer | Yes | Index of the face in the target video (0-based, sorted left to right). |
source_face_info | object | No | Coordinate information of the source face. When provided, skips internal re-detection to ensure consistent face ordering. |
target_face_info | object | No | Coordinate information of the target face. When provided, improves matching accuracy. |
source_face_info Fields
| Field | Type | Description |
|---|---|---|
face_url | string | Cropped face image URL returned by Detect Faces (output.faces_obj["0"].face_urls[i]). When provided, the backend uses this cropped image directly for the swap, skipping internal re-detection and ensuring consistent face identity. |
bbox | number[] | Face bounding box in pixels, format [x1, y1, x2, y2], where (x1, y1) is the top-left corner and (x2, y2) is the bottom-right corner. Taken from the region field returned by Detect Faces. |
kps | number[][] | 5 facial landmark keypoint coordinates, format [[x, y], ...], in order: left eye, right eye, nose tip, left mouth corner, right mouth corner. Taken from the landmarks field returned by Detect Faces. When provided, the backend uses them directly, skipping re-detection and improving alignment accuracy. |
target_face_info Fields
| Field | Type | Description |
|---|---|---|
face_url | string | Cropped face image URL of the target face, returned by Detect Faces (output.faces_obj["0"].face_urls[i]). When provided, the backend precisely matches the target face, avoiding mismatches caused by internal re-detection. |
bbox | number[] | Target face bounding box in pixels, format [x1, y1, x2, y2], where (x1, y1) is the top-left corner and (x2, y2) is the bottom-right corner. |
Task Status
After submitting a task, poll for status. Recommended polling interval: 10 seconds.
| Status | Description |
|---|---|
pending | Task created, waiting to be processed. |
processing | Task is being processed. |
completed | Task completed. Retrieve result URL from output.videos. |
failed | Task failed. Check error_message for the reason. |
Response Structure
Task Submission Response
| Field | Type | Description |
|---|---|---|
task_uuid | string | Unique task identifier for subsequent status queries. |
status | string | Initial status, typically pending. |
cost_credits | number | Credits consumed by this task. |
Task Completion Response
| Field | Type | Description |
|---|---|---|
task_uuid | string | Unique task identifier. |
model_id | string | Model ID (namifusion/faceswap-video). |
status | string | Task status. |
output.videos | string[] | List of face-swapped result video URLs. |
cost_credits | number | Credits consumed. |
created_at | string | Task creation time (ISO 8601). |
completed_at | string | Task completion time (ISO 8601). |
error_message | string | Error message (only returned when failed). |
Impact of Parameters on Output
| Parameter | Impact on Result |
|---|---|
single_face_mode: true | Automatically completes face swap, suitable for single-person scenarios without configuring face_mapping. |
single_face_mode: false + face_mapping | Precisely controls which faces to replace. Faces not specified in the mapping remain unchanged. |
face_enhance: true | Enables face enhancement, automatically smoothing skin and removing blemishes for a more refined and natural look, but increases processing time by ~20-50%. |
face_enhance: false | Default mode, no additional face processing, faster processing speed. |
model_style: "realistic" | Realistic style. Produces a natural look close to real faces, preserving lifelike skin tones and textures. |
model_style: "beautify" | Beautify style. Automatic skin smoothing and brightening for a refined, smooth appearance. |
model_style: "lossless" | Lossless style. Ultimate lossless mode that perfectly preserves all original facial details with the highest realism, nearly indistinguishable. |
Webhook
Instead of polling, you can provide a webhook_url in the request body to receive task results automatically. When the task completes (either completed or failed), the service sends a POST request to your URL with the full task result.
webhook_url is a top-level field alongside input, not nested inside it:
curl -X POST "https://www.namifusion.com/api/v1/marketplace/run/namifusion/faceswap-video" \
-H "X-API-Key: sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"input": {
"source_url": "https://example.com/source_face.jpg",
"target_url": "https://example.com/target_video.mp4",
"single_face_mode": true
},
"webhook_url": "https://your-server.com/callback"
}'
Webhook Payload
The payload POSTed to your webhook_url has the same structure as the task completion response:
{
"task_uuid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"model_id": "namifusion/faceswap-video",
"status": "completed",
"output": {
"videos": ["https://cdn.namifusion.com/result/faceswap_abc123.mp4"]
},
"cost_credits": 50,
"created_at": "2026-02-27T10:00:00Z",
"completed_at": "2026-02-27T10:01:30Z"
}
For failed tasks, the payload includes error_message and status: "failed".
Setting
webhook_urldoes not prevent you from also polling the task status — both can be used simultaneously.
Python Example
Submit task with webhook_url:
import requests
API_KEY = "sk-your-api-key"
BASE_URL = "https://www.namifusion.com/api/v1/marketplace/run"
HEADERS = {
"X-API-Key": API_KEY,
"Content-Type": "application/json",
}
# webhook_url is a top-level field alongside input, NOT nested inside input
resp = requests.post(
f"{BASE_URL}/namifusion/faceswap-video",
headers=HEADERS,
json={
"input": {
"source_url": "https://example.com/source_face.jpg",
"target_url": "https://example.com/target_video.mp4",
"single_face_mode": True,
},
"webhook_url": "https://your-server.com/callback",
},
).json()
print(f"Task submitted: {resp['task_uuid']}")
# No need to poll — results will be delivered to webhook_url automatically
Receive webhook callback (Flask):
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route("/callback", methods=["POST"])
def webhook():
payload = request.get_json()
task_uuid = payload["task_uuid"]
status = payload["status"]
if status == "completed":
video_url = payload["output"]["videos"][0]
print(f"Task {task_uuid} completed: {video_url}")
elif status == "failed":
error = payload.get("error_message", "Unknown error")
print(f"Task {task_uuid} failed: {error}")
return jsonify({"received": True}), 200
if __name__ == "__main__":
app.run(port=8080)
Notes
- URLs must be publicly accessible: Both
source_urlandtarget_urlmust be publicly downloadable URLs. Both HTTP and HTTPS are supported. - Face index sorting rule: Both
source_face_indexandtarget_face_indexstart from 0, sorted left to right by the x-coordinate of the face bbox's top-left corner. - Strongly recommended to pass face_info: If you have already called Detect Faces, passing the detected
bboxintoface_mappingcan avoid index inconsistency issues caused by internal re-detection in the face swap service. - Polling interval: Recommended to poll task status every 10 seconds. Video face swap typically completes in 30 seconds to several minutes, depending on video duration and resolution.
- Result field name: The output field is named
output.videos, returning the face-swapped video URL.
Related models
namifusion Image/Video Face Swap
NamiFusion Video Face Swap Model Supports images and videos, easy single or multi-person face swapping. Compatible with multiple model_style options, can output realistic results or one-click beauty-enhanced versions — natural and great-looking!
换脸
NamiFusion Faceswap v5 is a high-speed, cost-effective model designed for large-scale, real-time workflows, delivering lifelike results with automatic skin tone matching and professional quality.
Image FaceSwap Pro
Image FaceSwap Pro supports single-face automatic detection and multi-face precise mapping with keypoint pairs.
namifusion Image Face Swap
NamiFusion Face Swap Model Easy single or multi-person face swapping. Compatible with multiple model_style options, can output realistic results or one-click beauty-enhanced versions — natural and great-looking!