Kling 3.0 Motion Control
Make the character in one image repeat the motion of one 3–30 second video at 720p or 1080p, and choose whether the background comes from the video or the image; the result is up to 10 seconds with image orientation and up to 30 seconds with video orientation.
- Asynchronous: the create call returns a task ID; the video arrives when the task succeeds.
- Two inputs, both required: one character image and one motion video of 3 to 30 seconds. The character in the image performs the motion of the video.
character_orientationsets what the character faces follow and how long the result can be: at most 10 seconds withimage(the default), at most 30 seconds withvideo.- There is no
durationfield: the result is as long as your motion video, up to the limit of the orientation you chose. - Billed per second of the finished video, settled from the amount held at create, at 720p or 1080p. A failed task costs nothing.
Both Kling motion-control models are not on the live GET /v1/media/models list at the time of writing. While a model is off that list, creating a task for it is answered with 503 processing_unavailable and nothing is charged. Check the list before you build on it.
Opens this model in the API Explorer. Enter your BeatAPI API key to create a task: the call is real and is billed to your own balance.
Model IDs
Two models share this endpoint and the same inputs. The values below come straight from the gateway contract; only Kling 3.0 Motion Control accepts background_source.
Endpoint and authentication
POST https://api.beatapi.io/v1/videos/tasks
Authorization
string
Required
Your BeatAPI API key, sent as Bearer <BEATAPI_API_KEY>. Create keys in the Dashboard. Keep keys on your server; never ship them in a browser or mobile app.
Send the body as JSON with Content-Type: application/json. Idempotency-Key is optional: send a unique value (at most 255 characters) per logical request and reuse it only to retry that exact body. Within 24 hours a retry with the same key and body returns the first response again with Idempotent-Replayed: true; the same key with a different body returns 409 idempotency_conflict. Responses other than 2xx are not stored, so a retry after a 400 or 402 runs again.
How a request works
Create the task
POST the parameters below to the endpoint. A 201 means the task was accepted and its price reserved from your balance; the work runs in the background. Save data.id.
Wait for it to finish
Call GET /v1/tasks/{task_id} and wait data.poll_after_seconds between calls (5 s for images, 8 s for videos) until status is succeeded or failed. Or register a webhook for task.succeeded and task.failed; keep polling as the fallback, because a task stopped by the processing timeout sends no event.
Save the result
On succeeded, download every data.output.media[].url and store the files you need; BeatAPI does not promise how long result URLs stay available. On failed, read data.error_code and data.error_message: the reserved amount was returned to your balance, and data.retryable says whether sending the same request again can succeed.
Input modes
Request parameters
model
string
Required
The model to run.
Value: kling-3-motion-control
If the value is wrong
- Missing:
"model" is required - An image model sent to this endpoint:
"model" nano-banana-2 is served by POST /v1/images/tasks, not this endpoint
prompt
string
Optional
Optional text guidance about the character or the scene. The motion itself comes from the video.
Length: ≤ 2500 characters
- Length is counted in characters (a CJK character counts as one). An empty string is accepted.
If the value is wrong
- Longer than the limit:
"prompt" has an unsupported length
images
string[]
Required
The character image: exactly one link. This is who performs the motion.
Items: 1–1
Each item is a public https:// URL. For a local file, upload it first with POST /v1/files and pass the returned data.url.
- Send a list with one public HTTPS link; a local file can be uploaded with
POST /v1/filesand the returneddata.urlused here. - Image size, format and dimensions are not checked when the task is created.
If the value is wrong
- Missing:
"images" is required - An empty list:
"images" requires at least 1 item - More than one link:
"images" accepts at most 1 items - Not an https:// link:
"images[0]" must be a public HTTPS URL
reference_videos
string[]
Required
The motion video: exactly one link. The character in images repeats the motion in this video.
Items: 1–1
Each item is a public https:// URL. For a local file, upload it first with POST /v1/files and pass the returned data.url.
- Its length must be 3 to 30 seconds (see Media limits). The result is as long as this video, up to the limit set by
character_orientation. - The gateway reads the length from the file header with byte-range requests before the task is created, when the host allows it.
- A local file can be uploaded with
POST /v1/files(video up to 100 MB) and the returneddata.urlused here.
You are billed for the seconds of video that are produced, so trim the clip to the motion you need. With character_orientation: "image" the result is at most 10 seconds.
If the value is wrong
- Missing:
"reference_videos" is required - An empty list:
"reference_videos" requires at least 1 item - More than one link:
"reference_videos" accepts at most 1 items - Not an https:// link:
"reference_videos[0]" must be a public HTTPS URL - Shorter than 3 or longer than 30 seconds:
reference_videos[0] is 2 seconds long; this model takes reference video of 3 to 30 seconds. - The host answers with an error or an empty file:
reference_videos[0] could not be downloaded: the URL returned HTTP 404.
resolution
string
OptionalDefault: 720p
Output resolution. It is also the price tier: 1080p costs more per second than 720p.
Allowed values: 720p, 1080p
Default: 720p
- Lower case only. If you leave it out,
720pis used.
If the value is wrong
- A value not in the list (for example
480p,4kor1080P):"resolution" must be one of: [720p 1080p]
character_orientation
string
OptionalDefault: image
Whether the character’s orientation follows the character image (image) or the motion video (video).
Allowed values: image, video
Default: image
- It also sets the longest result: at most 10 seconds with
image, at most 30 seconds withvideo(see How the orientation sets the length). - If you leave it out,
imageis used, so a motion video longer than 10 seconds needsvideoexplicitly. - It sets how much is held on your balance when the task is created: the longest result the orientation allows (see Billing).
If the value is wrong
- A value not in the list:
"character_orientation" must be one of: [image video]
background_source
string
OptionalDefault: input_video
Where the background of the result comes from: input_video keeps the background of the motion video, input_image keeps the background of the character image.
Allowed values: input_video, input_image
Default: input_video
- If you leave it out,
input_videois used. - Only Kling 3.0 Motion Control accepts this field.
If the value is wrong
- A value not in the list:
"background_source" must be one of: [input_video input_image]
The gateway also checks these combinations before creating the task:
- exactly one character image and one uploaded motion video of 3 to 30 seconds; with character_orientation image the output is at most 10 seconds
Input media limits
The gateway reads every input before the task is created and refuses one outside these limits with a 400 bad_request that names the input. Nothing is charged.
- Only the motion video is checked against a length limit when the task is created: 3 to 30 seconds, measured from the file header with a 0.1-second tolerance. The message names the input by position, counting from 0 like the field errors:
reference_videos[0] is 45 seconds long; this model takes reference video of 3 to 30 seconds. - A clip whose length cannot be read (the host does not allow byte-range requests, or the file is not an MP4 or MOV) is not refused at this step and is not measured. The create call is refused only when the host answers with an error or an empty file, for example
reference_videos[0] could not be downloaded: the URL returned HTTP 404. - Use
imagewith clips of up to 10 seconds. For a motion video longer than 10 seconds, sendcharacter_orientation: "video". - Image size, format and dimensions are not checked when the task is created.
- Have a local file? Upload it with
POST /v1/files(png, jpg, jpeg or webp images up to 50 MB; mp4 or mov video up to 100 MB) and pass the returneddata.url.
How the orientation sets the length
There is no duration field. The result is as long as your motion video, and character_orientation caps it.
- The amount is settled when the task finishes from the usage reported for the video that was produced, normally the list rate per second for its length; the difference to the amount held is returned. If no usage is reported, the amount held is charged. See Billing.
Fields this model does not accept
Sending one of these is refused before anything is charged, instead of being ignored:
duration,aspect_ratio,generate_audio,seed,task_type,output_format,reference_images,reference_audios,quality,sound,watermarkand any other field of the other video models →field "duration" is not supported by model kling-3-motion-control(with the field you sent).- Any field the API does not know at all →
unknown field: <name>.
Request examples
Motion transfer
Replace the video link with your own MP4 or MOV of 3 to 30 seconds (there is no public sample video). character_orientation is left out, so image applies and the result is at most 10 seconds.
1080p, orientation follows the video
For a clip longer than 10 seconds: video allows a result of up to 30 seconds. Replace the video link with your own clip. A longer result holds more on your balance when the task is created.
Keep the background of the character image
The result keeps the background of the character image instead of the one in the motion video. Replace the video link with your own clip.
Responses
Create a task (201)
The task object. output is null until the task succeeds. Fields marked “while running” disappear once the task finishes.
Finished task
GET /v1/tasks/{task_id} returns HTTP 200 with status: "succeeded" and the result in data.output.
Output fields
Failed task
A failed task is still HTTP 200 on GET /v1/tasks/{task_id}: the failure is in the body. The reservation is returned in full, so nothing is charged.
Complete example
Create a task, wait for it with the server’s polling hint, and print the result URLs. Set BEATAPI_API_KEY in your environment and install requests.
Billing
- These prices apply once the model is listed; until then a create request is refused and nothing is charged.
- Billed per second of the finished video, by
resolution.character_orientationand the prompt do not change the rate. The table below prices an 8-second result. - The result is as long as your motion video, so the final price is not known when the task is created. The gateway holds the most the orientation allows: 10 seconds with
image, 30 seconds withvideo, at the rate of the resolution. That is about 1.40 (1080p) withimage, and about 4.20 (1080p) withvideo. The balance must cover that amount, or the create call fails with402 insufficient_credits. - When the task finishes, the amount is settled from the usage reported for the video that was produced, normally the list rate per second for its length, and the rest of the amount held is returned. If no usage is reported, the amount held is charged.
usage.credits_chargedandusage.credits_settledshow what was charged.usage.billable_duration_secondson this model reports the seconds held at create (10 or 30), not the length of the finished video; read the credits fields for what you paid. - A failed task, including one refused by moderation after submission, is refunded in full. A request refused before a task exists costs nothing.
Current list prices, the same as on Pricing. An account with a negotiated discount pays less; data.usage on the task always shows the amount actually charged.
Common errors
HTTP errors at a glance
Errors before a task exists arrive as a non-2xx response, and nothing is charged. Branch on error.code or error.retryable; message names the problem. The full list and retry policy are on Errors.
Differences between the two models
Authentication
Send your API key as Authorization: Bearer <BEATAPI_API_KEY>.
Headers
Send the body as JSON with Content-Type: application/json. Idempotency-Key is optional: send a unique value (at most 255 characters) per logical request and reuse it only to retry that exact body. Within 24 hours a retry with the same key and body returns the first response again with Idempotent-Replayed: true; the same key with a different body returns 409 idempotency_conflict. Responses other than 2xx are not stored, so a retry after a 400 or 402 runs again.
Request
The character image: exactly one link. This is who performs the motion.
Items: 1–1
Each item is a public https:// URL. For a local file, upload it first with POST /v1/files and pass the returned data.url.
- Send a list with one public HTTPS link; a local file can be uploaded with
POST /v1/filesand the returneddata.urlused here. - Image size, format and dimensions are not checked when the task is created.
If the value is wrong
- Missing:
"images" is required - An empty list:
"images" requires at least 1 item - More than one link:
"images" accepts at most 1 items - Not an https:// link:
"images[0]" must be a public HTTPS URL
The model to run.
Value: kling-3-motion-control
If the value is wrong
- Missing:
"model" is required - An image model sent to this endpoint:
"model" nano-banana-2 is served by POST /v1/images/tasks, not this endpoint
The motion video: exactly one link. The character in images repeats the motion in this video.
Items: 1–1
Each item is a public https:// URL. For a local file, upload it first with POST /v1/files and pass the returned data.url.
- Its length must be 3 to 30 seconds (see Media limits). The result is as long as this video, up to the limit set by
character_orientation. - The gateway reads the length from the file header with byte-range requests before the task is created, when the host allows it.
- A local file can be uploaded with
POST /v1/files(video up to 100 MB) and the returneddata.urlused here.
Notes: You are billed for the seconds of video that are produced, so trim the clip to the motion you need. With character_orientation: "image" the result is at most 10 seconds.
If the value is wrong
- Missing:
"reference_videos" is required - An empty list:
"reference_videos" requires at least 1 item - More than one link:
"reference_videos" accepts at most 1 items - Not an https:// link:
"reference_videos[0]" must be a public HTTPS URL - Shorter than 3 or longer than 30 seconds:
reference_videos[0] is 2 seconds long; this model takes reference video of 3 to 30 seconds. - The host answers with an error or an empty file:
reference_videos[0] could not be downloaded: the URL returned HTTP 404.
Where the background of the result comes from: input_video keeps the background of the motion video, input_image keeps the background of the character image.
Allowed values: input_video, input_image
Default: input_video
- If you leave it out,
input_videois used. - Only Kling 3.0 Motion Control accepts this field.
If the value is wrong
- A value not in the list:
"background_source" must be one of: [input_video input_image]
Whether the character’s orientation follows the character image (image) or the motion video (video).
Allowed values: image, video
Default: image
- It also sets the longest result: at most 10 seconds with
image, at most 30 seconds withvideo(see How the orientation sets the length). - If you leave it out,
imageis used, so a motion video longer than 10 seconds needsvideoexplicitly. - It sets how much is held on your balance when the task is created: the longest result the orientation allows (see Billing).
If the value is wrong
- A value not in the list:
"character_orientation" must be one of: [image video]
Optional text guidance about the character or the scene. The motion itself comes from the video.
Length: ≤ 2500 characters
- Length is counted in characters (a CJK character counts as one). An empty string is accepted.
If the value is wrong
- Longer than the limit:
"prompt" has an unsupported length
Output resolution. It is also the price tier: 1080p costs more per second than 720p.
Allowed values: 720p, 1080p
Default: 720p
- Lower case only. If you leave it out,
720pis used.
If the value is wrong
- A value not in the list (for example
480p,4kor1080P):"resolution" must be one of: [720p 1080p]
Response
The task object. output is null until the task succeeds. Fields marked “while running” disappear once the task finishes.

