Fades between 2-second AI shots: the 1 s cap and the 8-fade chain
Joining 15 two-second Wan 3.0 shots on Sume Timeline: a fade can be at most 1 s, at most half of the shorter shot, and 8 chained fades are refused. Python.

When you join 2 second shots on Sume Timeline, a fade can be at most 1 second, because Timeline limits a transition to 1 second and to 50 percent of the shorter neighbouring slot. Nine adjacent fades are refused with too_many_chained_transitions, so a 15 shot cut needs a hard cut at least once in every 8 joins. A 0.5 second fade at 30 fps is 15 frames, which keeps it frame aligned.
This matters for fast montage built from Wan 3.0, whose shortest clip is 2 seconds. The Kling 4.0 pitch is a long take with up to 10 keyframes, per the fal explainer (read 2026-10-05). If you assemble the same idea from short shots on Sume, the transition rules below are what you work within.
The three limits
The Timeline docs set three limits on video[].transition. It applies only to slots after the first. The type is one of fade, wipeleft, wiperight, slideup, slidedown and dissolve. The duration is at most 1 second, at most 50 percent of the shorter neighbour, and at least one output frame.
For two 2 second shots the half-of-the-shorter rule gives 1 second, which equals the cap, so 1 second is the maximum. For a 1 second shot the maximum would be 0.5. The refusal codes are transition_too_long and transition_not_frame_aligned. A separate refusal, too_many_chained_transitions, fires when more than 8 fades are adjacent, with the instruction to insert a hard cut.
Transition rules for 2 second shots
| Question | Answer |
|---|---|
| Longest fade between two 2 s shots | 1 s |
| Longest fade next to a 1 s shot | 0.5 s |
| Frame aligned at 30 fps | 0.5 s = 15 frames |
| Most adjacent fades | 8 (a ninth is refused) |
| Joins in a 15 shot cut | 14 |
| Slots before auto chunking | 12 (the default strategy chunks above that) |
A plan for fifteen shots
A plan for 15 shots is to fade every join except every eighth. That gives seven fades in a row, one hard cut, then six fades, with no chain above eight. The render is billed $0.10 for the minute, and the shots are 15 Wan 3.0 jobs at $0.25 each at 720p, so the whole 30 second cut is about $3.85.
Pick the transition type by the cut. A fade or dissolve suits a change of place, the wipeleft and wiperight types suit a directional move, and slideup and slidedown suit a vertical reveal. All of them follow the same duration limits. The documented remedy for the chain limit is a hard cut, so use that, and run /plan to confirm that a mixed sequence passes before you pay for a render.
With fifteen slots the render crosses the 12-slot line, and the default auto strategy chunks the work. Only the explicit single strategy is refused above 12 slots, with render_strategy_unsafe, so leave the strategy at its default. Soft warnings, such as a transition snapped to a frame boundary or a short source that was padded or looped, do not fail the job and appear in warnings[] on the result.
Fades also compress the visible content. Two clips that overlap for half a second show less of each, so for a beat-matched cut keep the fades short, and use the plan endpoint to check the declared starts before you pay for a render.
Build the slots
This builds the video[] slots and checks the chain rule before you send them. It prints the slots and the longest fade run.
shots = 15
shot_len = 2
fade = 0.5
slots = []
for i in range(shots):
slot = {
"source_url": f"https://media.sume.com/artifacts/artf_demo/shot{i + 1:02d}.mp4",
"start": i * shot_len,
"duration": shot_len,
}
if i > 0 and i % 8 != 0:
slot["transition"] = {"type": "fade", "duration": fade}
slots.append(slot)
run = longest = 0
for slot in slots:
run = run + 1 if "transition" in slot else 0
longest = max(longest, run)
assert fade <= 1 and fade <= 0.5 * shot_len
assert longest <= 8
print(len(slots), "slots, longest fade run", longest)Render it
Send the slots in a render body with audio.duration_seconds 30 and output.fps 30. If you have no voice-over yet, audio.mode silence declares the length without a file. Run /plan first, because it is unbilled and returns the segment count, billable_minutes and estimated_cost_usd_micros, then render with an Idempotency-Key. Poll the job as in the jobs docs. Keep the fade at 0.5 seconds unless the shots are longer, and remember that the output frame rate you choose also decides which fade lengths are frame aligned: 0.5 seconds is a whole number of frames at 24 and 30 fps, but not at 25.
Sources
Related posts
More in Media tools
- Video captions take a public HTTPS URL; other media tools do not
Which URL each Sume video tool accepts: captions fetch a public HTTPS clip, while trim, filter, frames, inspect and timeline need your media.sume.com file.
- Video captions rejects a signed URL: what to send instead
Sume video captions only fetches public HTTPS video URLs and rejects signed, private and localhost links. How to caption a clip that sits behind a signed link.
- Video filter 300 s source cap: trim a long clip first, then filter
Sume video filter rejects sources over 300 seconds while trim and detach take 1800. The output_duration_exceeded error, and a trim then filter order that fits.
- Dry-run a Sume video crop with video-filter check before a batch
POST /v1/video-filter/check validates a crop program without a job, credits or an encode. Run it first, then crop a batch of ad clips for new ratios.
Written by Sume