One dance, 50 mascots: Kling motion control batch cost and keys

One 12-second reference against 50 stills on Sume motion control: 50 x $1.89 = $94.50. Key each job by still and reference so a retry never double-bills.

5 min readSume
All posts

One 12-second reference and 50 character stills is 50 motion control jobs at $1.89 each, which is $94.50 in credits. Each job gets its own Idempotency-Key built from the still and the reference, so a crashed worker that restarts submits the same keys and never pays for a mascot twice.

Why this shape suits motion control

A shared dance is the cleanest use of the route: the reference is fixed, the stills vary, and every output has the same timing. A brand with 50 mascots, a game with 50 skins or a school with 50 class characters can all use the same performance.

Because the reference is one file, you measure it once, trim it once at $0.02, and declare duration_seconds: 12 on every job. The price per job is the same and your budget is a multiplication.

The budget

Prices come from $0.126 list x 1.25 = $0.1575 per second, reserved at admit and refunded on a failed job.

Batch cost for a 12-second shared reference, USD (read 2026-10-05)
StillsJobsPer jobTotal reserve
551.899.45
10101.8918.90
25251.8947.25
50501.8994.50

A key per pair

The key should be a pure function of the inputs. A hash of the still URL, the reference URL and the declared length gives the same key for the same job on every run. If a worker dies after submit but before it saves the job id, the retry sends the same key with the same body and gets the same job back.

import hashlib

REF = "https://example.com/dance.mp4"
SECONDS = 12

def job_key(still_url: str) -> str:
    raw = f"{still_url}|{REF}|{SECONDS}".encode()
    return "mc-" + hashlib.sha256(raw).hexdigest()[:32]

stills = [f"https://example.com/mascot-{i}.png" for i in range(50)]
keys = [job_key(s) for s in stills]
assert len(set(keys)) == 50
print(keys[0], len(keys), round(len(keys) * SECONDS * 0.1575, 2))

Keep the batch inside your balance

Check the balance against $94.50 before you start. A 402 on job 38 leaves 37 finished clips and a partial set, which is harder to explain than a refusal on job one. Submit in waves of ten, check each wave, and use a webhook to learn about completions instead of polling 50 jobs.

If a request returns 429 queue_full, wait and resubmit the same body with the same key. If it returns 429 rate_limited, slow the wave. Neither counts as a failed job, since nothing was admitted.

Quality control across 50

Fifty clips are too many to watch in full. Pull one frame from each with POST /v1/video-frames, at a time inside the clip such as 6 seconds, and lay them out in a contact sheet. A character that lost its face or its outfit shows at a glance. Regenerate only the failures with a fresh key, which costs $1.89 each.

Keep the stills consistent in size and framing. A mix of close-ups and full-body shots gives uneven results with one reference, because the performance was filmed for one framing. Crop all 50 stills to the same shape before you submit, and the batch behaves as one.

Related posts

More in Use cases

All Use cases posts

Written by Sume