MixMedia API
RUEN
API keys Sign inTry it
Open as Markdown
← Try it on the website

Higgsfield Genjutsu

Higgsfield · ~3 min
from $0.414per second

One clip, three modes: motion transfer, object swap and restyle. 4 to 30 seconds, up to 1080p.

Higgsfield Genjutsu takes a finished clip and changes the reality in it without reshooting the motion.

Motion transfer builds a new scene from your photos — a character, a place, a style — and keeps the original motion, camera and timing.

Object swap changes a chosen person, outfit, product or object. The rest of the shot stays as filmed.

Restyle applies a chosen visual style and keeps the clip’s motion and original audio. Photos are optional: without them the style is applied to whoever is already in the frame.

The video is at least 4 seconds; longer than 30 seconds is trimmed to 30. Resolution is 480p, 720p or 1080p. The prompt is optional. Every mode costs the same, per second of your clip.

One model, higgsfield-genjutsu · ~3 min. The mode is the input.mode field.

Modes

One ID, higgsfield-genjutsu. input.mode chooses what happens to the clip. Omitted, it is motion transfer. The official ids work too: higgsfield/genjutsu/object-swap/v1.0 and higgsfield/genjutsu/restyle/v1.0 select the mode, so mode can be left out.

modeWhat it doesWhat to send
motion-transferMotion, camera and timing come from the video; the look comes from the photosvideo_url + image_urls (1–8)
object-swapReplaces a person, outfit or object in the clip. The rest of the shot staysvideo_url + image_urls (1–8)
restyleThe same clip in a chosen style. The source motion and audio stayvideo_url + preset_id. image_urls — optional, up to 5

Shared by all three: the video is at least 4 seconds, longer than 30 seconds is trimmed to 30, and the result has the same length. prompt may be omitted. resolution: 480p, 720p (default) or 1080p. The mode does not change the price.

Object swap needs a source frame of at least 409,600 pixels (width × height). Ordinary HD is fine; a tiny preview is not.

Styles for restyle

Style list: GET https://mixmedia.tech/api/v1/genjutsu/presets. No key. preset_id is the item's id, not its name and not the preview image.

{
  "code": 200,
  "msg": "success",
  "data": {
    "items": [
      {
        "id": "c2143317-f28d-4c3c-a0b8-39bd547e08a7",
        "name": "Cel-Shaded CG Anime",
        "preview_url": "https://…/style.webp"
      }
    ]
  }
}

The list changes. If a saved preset_id is no longer accepted, fetch the list again and use a current id.

Price

ResolutionPrice per second of your video
480p$0.414
720p$0.886
1080p$2.122
  • Price = per-second price × clip length, rounded up to $0.001. Charged when the task is created and fully refunded if it fails.
  • You pay per second of your video (4 to 30 s). A clip longer than 30 s is trimmed to 30; the result has the same length. prompt may be omitted.

Media limits

TypeLimits
Images1–8 for motion transfer and object swap; 0–5 for restyle. JPG / PNG / WebP; public https or files/upload — up to 30 MB per file
Videoone clip, video_url; 4 s to 30 s (longer is trimmed to 30); MP4 / MOV → MP4 on the server; upload ≤ 200 MB

Photos — public https or upload; video and audio — files/upload only.

Parameters (field input)

ParameterDescriptionValues (default in bold)
modeMode: motion-transfer copies motion onto your photos, object-swap replaces a person or object, restyle keeps the clip and applies a style. Omit it when calling an official model id: …/object-swap/v1.0 and …/restyle/v1.0 select the mode themselvesmotion-transfer · object-swap · restyle
promptWhat happens in the clip: scene, motion, camera, light, styletext, up to 10000 chars (optional, default empty)
video_urlMotion video (MP4): one clip, at least 4 s. Longer than 30 s is trimmed to 30. Upload it via files/upload first"https://…"
image_urlsCharacter photos (https): look, face, clothes["https://…"], up to 8
preset_idStyle for restyle: a UUID from GET /api/v1/genjutsu/presets. Not used by the other modesstyle UUID, required when mode is restyle
resolutionVideo resolution480p · 720p · 1080p

Examples

Motion transfer

curl -X POST https://mixmedia.tech/api/v1/jobs/createTask \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"higgsfield-genjutsu","input":{"mode":"motion-transfer","prompt":"Keep the face from the photo, take the motion from the video","video_url":"https://mixmedia.tech/files/<id>.mp4","image_urls":["https://mixmedia.tech/static/img/previews/gpt-t2i.jpg"],"resolution":"720p"}}'
import os, requests

r = requests.post(
    "https://mixmedia.tech/api/v1/jobs/createTask",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    json={
      "model": "higgsfield-genjutsu",
      "input": {
        "mode": "motion-transfer",
        "prompt": "Keep the face from the photo, take the motion from the video",
        "video_url": "https://mixmedia.tech/files/<id>.mp4",
        "image_urls": [
          "https://mixmedia.tech/static/img/previews/gpt-t2i.jpg"
        ],
        "resolution": "720p"
      }
    },
)
print(r.json())  # {"code": 200, "data": {"taskId": "..."}}
const r = await fetch("https://mixmedia.tech/api/v1/jobs/createTask", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "model": "higgsfield-genjutsu",
    "input": {
      "mode": "motion-transfer",
      "prompt": "Keep the face from the photo, take the motion from the video",
      "video_url": "https://mixmedia.tech/files/<id>.mp4",
      "image_urls": [
        "https://mixmedia.tech/static/img/previews/gpt-t2i.jpg"
      ],
      "resolution": "720p"
    }
  }),
});
console.log(await r.json()); // { code: 200, data: { taskId: "..." } }

Object swap

curl -X POST https://mixmedia.tech/api/v1/jobs/createTask \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"higgsfield-genjutsu","input":{"mode":"object-swap","prompt":"Replace the person with the character in the photo","video_url":"https://mixmedia.tech/files/<id>.mp4","image_urls":["https://mixmedia.tech/static/img/previews/gpt-t2i.jpg"],"resolution":"720p"}}'
import os, requests

r = requests.post(
    "https://mixmedia.tech/api/v1/jobs/createTask",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    json={
      "model": "higgsfield-genjutsu",
      "input": {
        "mode": "object-swap",
        "prompt": "Replace the person with the character in the photo",
        "video_url": "https://mixmedia.tech/files/<id>.mp4",
        "image_urls": [
          "https://mixmedia.tech/static/img/previews/gpt-t2i.jpg"
        ],
        "resolution": "720p"
      }
    },
)
print(r.json())  # {"code": 200, "data": {"taskId": "..."}}
const r = await fetch("https://mixmedia.tech/api/v1/jobs/createTask", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "model": "higgsfield-genjutsu",
    "input": {
      "mode": "object-swap",
      "prompt": "Replace the person with the character in the photo",
      "video_url": "https://mixmedia.tech/files/<id>.mp4",
      "image_urls": [
        "https://mixmedia.tech/static/img/previews/gpt-t2i.jpg"
      ],
      "resolution": "720p"
    }
  }),
});
console.log(await r.json()); // { code: 200, data: { taskId: "..." } }

Restyle

curl -X POST https://mixmedia.tech/api/v1/jobs/createTask \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"higgsfield-genjutsu","input":{"mode":"restyle","video_url":"https://mixmedia.tech/files/<id>.mp4","preset_id":"<preset_id>","resolution":"720p"}}'
import os, requests

r = requests.post(
    "https://mixmedia.tech/api/v1/jobs/createTask",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    json={
      "model": "higgsfield-genjutsu",
      "input": {
        "mode": "restyle",
        "video_url": "https://mixmedia.tech/files/<id>.mp4",
        "preset_id": "<preset_id>",
        "resolution": "720p"
      }
    },
)
print(r.json())  # {"code": 200, "data": {"taskId": "..."}}
const r = await fetch("https://mixmedia.tech/api/v1/jobs/createTask", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "model": "higgsfield-genjutsu",
    "input": {
      "mode": "restyle",
      "video_url": "https://mixmedia.tech/files/<id>.mp4",
      "preset_id": "<preset_id>",
      "resolution": "720p"
    }
  }),
});
console.log(await r.json()); // { code: 200, data: { taskId: "..." } }

Create and result

  1. POST /api/v1/jobs/createTask with model and input.
  2. Poll GET /api/v1/jobs/recordInfo?taskId=… every 3–5 s (or a callback).

Successful createTask (HTTP 200)

{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "task_...",
    "task_id": "task_...",
    "status": "submitted"
  }
}

Completed task (recordInfo)

{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "task_...",
    "task_id": "task_...",
    "state": "success",
    "status": "completed",
    "costUsd": "0.384",
    "refunded": false,
    "resultJson": {
      "videos": [
        {
          "url": "https://…/out.mp4"
        }
      ],
      "duration": 8
    }
  }
}

Aliases: task_id = taskId; status: pending / processing / completed / failed alongside state. Clip URL is in resultJson. size is an alias of aspect_ratio in input.

Photos can be any public https links or uploads via files/upload. Videos and audio — via files/upload only.

Error handling

API responses are JSON {"code", "msg", "data"}; errors also have a string error field (type). On /api/v1/* the HTTP status matches body code.

Example response bodies

400

{
  "code": 400,
  "msg": "input.duration: must be between 4 and 30, or \"auto\" / -1",
  "data": null,
  "error": "invalid_request_error"
}

401

{
  "code": 401,
  "msg": "Authentication failed. Please check your API key",
  "data": null,
  "error": "authentication_error"
}

402

{
  "code": 402,
  "msg": "Insufficient balance. Please top up and try again. Available: $0.01, required: $0.015. Top up at https://mixmedia.tech/cabinet/billing",
  "data": {
    "balance": "0.0100",
    "required": "0.0150",
    "currency": "USD",
    "topUpUrl": "https://mixmedia.tech/cabinet/billing"
  },
  "error": "payment_required"
}

429

{
  "code": 429,
  "msg": "Rate limit exceeded: 10 createTask/upload requests per 10 s per key. Retry after 8s",
  "data": null,
  "error": "rate_limit_error"
}

500

{
  "code": 500,
  "msg": "Internal server error",
  "data": null,
  "error": "server_error"
}

Codes on createTask / upload

codeerrorMeaningWhat to do
400invalid_request_errorInvalid parameter or bodySee msg
400unsupported_modelUnknown modelModel list
400nsfw_content_detectedModeration / content policy — msg / failMsg is the upstream text verbatimRead the refusal text, change the prompt or files
401authentication_errorMissing or invalid keyCheck the key
402payment_requiredNot enough balanceTop up
403permission_errorNo accessContact support
429rate_limit_errorToo many requestsWait for Retry-After
505model_disabledModel temporarily disabledPick another
500server_errorOur failureRetry later

Example msg values: Authentication failed. Please check your API key (401); Insufficient balance. Please top up and try again… (402).

Task errors (recordInfo)

If the task was created and then failed: state: "fail" (alias status: "failed"), failCode / failMsg, and error: { code, message, type }. Money is refunded (refunded: true).

failCodeerror.typeMeaning
400nsfw_content_detected / invalid_request_errorModeration — failMsg is upstream text verbatim
422invalid_request_errorThe model rejected the parameters (length, mode, resolution, file)
501server_errorThe model could not generate (failMsg)
504timeout_errorTimed out — retry
500 / 503server_errorService temporarily unavailable

Rate limits

WhatLimit
createTask and upload20 per 10 s per key
recordInfo / list / balance100 per 10 s per key

Over the limit — HTTP 429 and Retry-After.

© 2026 MixMedia