Kling motion control returns 400 on reference_image_urls or model

The Sume motion-control body is strict. It rejects Video 1.0 words such as reference_image_urls, reference_video_urls, model and provider endpoint fields.

5 min readSume
All posts

A request to Sume's Kling motion control routes that carries reference_image_urls, reference_video_urls, model or a provider endpoint field is rejected. The body is strict on purpose. You send one visual source, one motion_video_url and a duration_seconds, and nothing from the /v1/videos vocabulary.

Why the route is strict

Sume's kling-3 video id does not take reference_*_urls. If the motion route took them, it would be a back door to a reference input that kling-3 refuses. So the route rejects the Video 1.0 words, and the model id is fixed by the path: all four routes store kling/3.0/motion-control.

That is also why there is no model field. The path is the model.

Map the old fields

If you ported a call from a video route, change it like this.

Video request fields and motion control fields (read 2026-10-05)
You sentSend instead
model: "kling-3"nothing; use the motion-control path
reference_image_urls: [one image]image_url, or avatar_id / avatar_handle
reference_video_urls: [one clip]motion_video_url
duration: 10duration_seconds: 10 (1 to 30)
generate_audio: falsekeep_original_sound: false

A body that passes

Exactly one visual source is allowed: image_url, or an avatar by id or handle, not both. character_orientation is video (the default) or image. A prompt is optional and only steers appearance, because the reference video drives all of the motion.

{
  "image_url": "https://example.com/character.png",
  "motion_video_url": "https://example.com/walk.mp4",
  "duration_seconds": 12,
  "keep_original_sound": false,
  "character_orientation": "video",
  "prompt": "Same jacket, warmer light",
  "mode": "async"
}

What to check first

When you see a 400, diff your body against the list above before you look anywhere else. The cause is nearly always a field that came from a video-route example. Remove it, keep the one visual source, and resubmit with a new idempotency key, since the body changed.

Do not try to force a reference through the prompt. The prompt does not carry motion. If you want a model that takes reference videos as inputs rather than as a motion track, the Sume catalog has other ids that list video_url references, and the right one depends on the length and the ratio that you need.

Three more causes of a 400

The Video 1.0 words are the common cause, but they are not the only one. Sending both image_url and avatar_id breaks the one-visual-source rule. Leaving out motion_video_url breaks the required field. And a duration_seconds of 0, or of 31 or more, falls outside the range of 1 to 30.

A fourth cause is a URL that is not public HTTPS. The still and the reference must be reachable by the worker. A signed link that expires in a minute, or a link behind a login, will fail later in the job rather than at submit, so test the link from a clean machine before you send it.

Keep a small validator in your own code that mirrors these rules. It costs nothing, it fails in your logs with a readable message, and it saves a round trip for every mistake it catches.

Idempotency after a fix

A body that changed needs a new Idempotency-Key. If you retry with the same key and a different body, the API answers 409 idempotency_conflict, which is the opposite of what you want. Generate the key from the content of the job, such as a hash of the still, the reference and the length, and a fixed body always maps to the same key.

Related posts

More in Developers

All Developers posts

Written by Sume