Timeline refuses a 180-second Short: clips end more than 0.5 s early

Timeline 1.0 allows video coverage to stop at most 0.5 seconds before the end of the audio spine. Check slot ends in Python before you plan a 180-second Short.

5 min readSume
All posts

Short answer

In Timeline 1.0 the on-screen slots must reach to within 0.5 seconds of the end of the audio spine. A 180-second Short built from slots that end at 179.4 leaves a 0.6-second gap and breaks the rule. Compute the gap before you send the request, and extend the last slot, or shorten audio.duration_seconds, until it is 0.5 or less.

The rule

The timeline docs say a video slot has a duration of at least 0.2 seconds, and that coverage can stop at most 0.5 seconds before the end of the spine. The spine is the audio: either a real file or a declared length with audio.mode silence. The first slot must start at 0, starts must increase, and slots may not overlap beyond their transition. Those are all compile-time checks. The plan endpoint runs the compiler without creating a job, so it is the cheap place to find out.

YouTube's Shorts page says a Short can run up to 3 minutes (read 2026-10-05), so a 180-second spine is the longest case, and it is the one where ten or twenty clips make a small gap easy to miss.

Cases at a 180-second spine

Gap is the spine length minus the end of the last slot.

Coverage gap at a 180-second spine, read 2026-10-05
Last slot endGapWithin 0.5 s?
180.00.0Yes
179.50.5Yes, at the limit
179.40.6No, extend the last slot
170.010.0No, a clip is missing

Pre-check in Python

The function takes the slot starts and durations you plan to send. It reports the gap and the verdict. Transitions complicate on-spine timing because the compiler compensates for the crossfade overlap, so use the declared starts, which the docs say are authoritative.

def coverage_gap(spine, slots):
    end = max(s["start"] + s["duration"] for s in slots)
    return round(spine - end, 3)

slots = [{"start": 0, "duration": 60},
         {"start": 60, "duration": 60},
         {"start": 120, "duration": 59.4}]
gap = coverage_gap(180, slots)
print(gap, "ok" if gap <= 0.5 else "extend the last slot")

Other timing errors to expect

  • timeline_must_start_at_zero: the first slot starts at something other than 0.
  • invalid_segment_timing or segment_overlap: starts do not increase, or slots overlap past the crossfade.
  • transition_on_first_segment: a transition on slot 0.
  • too_many_chained_transitions: more than 8 adjacent fades; insert a hard cut.

Next step

When the gap is within range, send the body to the plan endpoint, read billable_minutes (3 for 180 seconds, so $0.30 at the documented rate) and render with an Idempotency-Key. The timeline docs list every refusal code.

A habit that avoids the whole class of bug: compute the slot starts from the durations rather than typing them. If each start is the previous start plus the previous duration, overlaps and gaps in the middle cannot happen, and the only number to check is the end of the last slot against the spine. When the spine is a voice file, take its length from the probe in video inspect and use that for audio.duration_seconds, so the 0.5-second window is measured against the real audio.

If you plan to use crossfades, remember the compiler compensates for the overlap, so keep the declared starts as your timeline of record and let the plan call tell you whether the arrangement compiles.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume