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

Kling 3.0 Motion Control

Kuaishou · ~5 min
from $0.134per second

The character from your photo copies the motion, gestures and expressions from a video. 3–30 second clips, 720p or 1080p.

Kling 3.0 Motion Control takes one character photo and a motion video and brings the character to life: it repeats the motion, gestures and expressions from the clip.

Orientation «Like the video» — pose and turns as in the clip, video 3–30 seconds. «Like the photo» — the character keeps the angle from the photo, video 3–10 seconds. Longer is trimmed. The clip's sound can be kept. Quality Standard (720p) or Pro (1080p). You pay per second of your video.

One model, kling-3.0-motion-control · ~5 min. Send your video video_url and photos image_urls.

Price

ResolutionPrice per second of your video
720p$0.134
1080p$0.179
  • Price = per-second price × clip length, rounded up to $0.001. Charged when the task is created and fully refunded if it fails.
  • character_orientation: "image" — video up to 10 s (longer is trimmed to 10).
  • You pay per second of your video (3 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 (character); JPG / PNG / WebP; public https link or files/upload — up to 30 MB per file
Videoone clip, video_url; 3 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)
promptWhat happens in the clip: scene, motion, camera, light, styletext, up to 2500 chars (optional, default empty)
video_urlMotion video (MP4): one clip, 3–30 s with character_orientation: "video", 3–10 s with "image" (longer is trimmed). Upload it via files/upload first"https://…"
image_urlsCharacter photos (https): look, face, clothes["https://…"], 1–1
character_orientationvideo — pose and turns follow the video (clip up to 30 s), image — the angle follows the photo (clip up to 10 s)video image
resolutionQuality = the Kling mode: 720p — Standard (std), 1080p — Pro (pro). You can also send mode: std / pro720p · 1080p
keep_original_soundKeep the sound of your video in the resulttrue false (default true)

Examples

Video + photo

curl -X POST https://mixmedia.tech/api/v1/jobs/createTask \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"kling-3.0-motion-control","input":{"prompt":"The character from the photo repeats the dance from the video","video_url":"https://mixmedia.tech/files/<id>.mp4","image_urls":["https://mixmedia.tech/static/img/previews/gpt-t2i.jpg"],"character_orientation":"video","resolution":"720p","keep_original_sound":true}}'
import os, requests

r = requests.post(
    "https://mixmedia.tech/api/v1/jobs/createTask",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    json={
      "model": "kling-3.0-motion-control",
      "input": {
        "prompt": "The character from the photo repeats the dance from the video",
        "video_url": "https://mixmedia.tech/files/<id>.mp4",
        "image_urls": [
          "https://mixmedia.tech/static/img/previews/gpt-t2i.jpg"
        ],
        "character_orientation": "video",
        "resolution": "720p",
        "keep_original_sound": True
      }
    },
)
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": "kling-3.0-motion-control",
    "input": {
      "prompt": "The character from the photo repeats the dance from the video",
      "video_url": "https://mixmedia.tech/files/<id>.mp4",
      "image_urls": [
        "https://mixmedia.tech/static/img/previews/gpt-t2i.jpg"
      ],
      "character_orientation": "video",
      "resolution": "720p",
      "keep_original_sound": true
    }
  }),
});
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.

Try the same models on the website or see prices.

© 2026 MixMedia