Head Swap – Generate

namifusion/head-swap/generate

Replace selected heads in the video with your reference images using Wan2.2-Animate. Keeps the original audio track.

Examples

Head Swap – Generate example 1

Parameters

NameTypeDefaultConstraintsDescription
track_manifest_url *Track manifest URLtexttrack_manifest_url returned by the analyze model
mappings *Head mappingsarray<object>Array of {obj_id, img_urls}. obj_id comes from analyze output; 1-3 reference image URLs per head.
obj_id *Head obj_idnumber
img_urls *Reference imagesimage_upload_group1–3 items
resolutionResolutionselect720p480p | 720p
seedSeednumber

Output fields

FieldTypeDescription
videosarrayResult video URL(s), original audio track preserved

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/head-swap/generate" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "input": {
    "track_manifest_url": "value",
    "mappings": [
      {
        "obj_id": 1,
        "img_urls": [
          "https://example.com/input.jpg"
        ]
      }
    ],
    "resolution": "720p"
  }
}'

# 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/head-swap/generate",
    headers=HEADERS,
    json={
        "input": {
            "track_manifest_url": "value",
            "mappings": [
                {
                    "obj_id": 1,
                    "img_urls": [
                        "https://example.com/input.jpg"
                    ]
                }
            ],
            "resolution": "720p"
        }
    },
)
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 7200s server-side.
deadline = time.time() + 7260
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/head-swap/generate", {
  method: "POST",
  headers: { ...HEADERS, "Content-Type": "application/json" },
  body: JSON.stringify({
    "input": {
      "track_manifest_url": "value",
      "mappings": [
        {
          "obj_id": 1,
          "img_urls": [
            "https://example.com/input.jpg"
          ]
        }
      ],
      "resolution": "720p"
    }
  }),
});
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 7200s server-side.
const deadline = Date.now() + 7260 * 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

Head Swap – Generate

Step 2 of the head swap pipeline. Replaces the selected heads in the video with your reference images using Wan2.2-Animate. Keeps the original audio track.

Input

FieldTypeRequiredNotes
video_urlstring (video URL)yesSame video as the analyze step; up to 30 seconds
track_manifest_urlstringyesReturned by namifusion/head-swap/analyze
mappingsarray of {obj_id, img_urls}yesobj_id from analyze output; 1-3 reference image URLs per head
resolution"480p" | "720p"noDefault 720p; must match the analyze step
seednumbernoRandom seed

Output

  • videos[0]: the finished video URL (original audio track preserved)

Typical flow

  1. Run namifusion/head-swap/analyze on your video
  2. Pick the obj_id(s) to replace from the analyze output
  3. POST /run/namifusion/head-swap/generate with track_manifest_url + mappings
  4. Poll GET /run/tasks/{task_uuid} until completed

Pricing: 720p: 75 credits per 5s unit; 480p: 40 credits per 5s unit; videos are capped at 30s.