TTS word timestamps to Timeline slide starts in Python
Call the Sume TTS Router with word timestamps, find the word that opens each slide, and build the Timeline video array of start times in a short Python script.

Ask the TTS Router for timestamps: {words: true}, then match the first word of each slide's line to the returned words[] to get a start time for every slide. Feed those starts into the video[] array of a Timeline 1.0 render. This keeps pictures changing exactly when the narrator reaches them, instead of on a fixed interval.
Script
The function below turns a words list into slide entries. It does not call the network, so you can test it first. Each slide keeps its own start and runs until the next one; the last runs to the audio end.
def slides(words, firsts, urls, total):
"""words: [{word,start,end}], firsts: first word of each slide."""
norm = [w["word"].lower().strip(".,!?") for w in words]
starts, i = [], 0
for first in firsts:
while i < len(norm) and norm[i] != first.lower():
i += 1
if i == len(norm):
raise ValueError(f"word not found: {first}")
starts.append(words[i]["start"])
ends = starts[1:] + [total]
return [{"source_url": u, "start": s, "duration": round(e - s, 2)}
for u, s, e in zip(urls, starts, ends)]
words = [{"word": "Welcome", "start": 0.0, "end": 0.4},
{"word": "Kitchen", "start": 3.1, "end": 3.6}]
print(slides(words, ["Welcome", "Kitchen"], ["a.jpg", "b.jpg"], 6.0))Request fields
| Field | Meaning |
|---|---|
| timestamps.words | true returns words[] on the completed job result, each with word, start and end |
| segmentation | mode sentence needs timestamps.words and returns gapless segments |
| Price | $0.0475 per 1,000 characters |
| Transcript | Up to 20000 characters |
Limits
A repeated first word matches the first occurrence after the previous slide, so pick distinctive opening words. Timestamps describe the audio you generated, not a different edit of it. In Timeline, video[0].start must be 0, later starts must increase, each slot must be at least 0.2 seconds long and coverage may trail the spine by at most 0.5 seconds, so run the unbilled plan call before rendering. Slide URLs must be your workspace's media.sume.com files, and the voice also needs a voice.id or avatar selector on the TTS request.
Sources
Related posts
More in Developers
- Twilio Play 40-minute file limit vs Sume TTS 1,200-second cap
Twilio warns that a played file over 40 minutes can drop the call. Sume TTS fails audio past 1,200 seconds, so a hold message fits. Format and caching notes.
- TypeScript 7: an exhaustive switch over Sume job statuses
Turn a Sume job record into done, failed, canceled or running with a never check, so a new status breaks the build. Compiled with tsc 7.0.2 in strict mode.
- Bulk run says completed but UGC variants failed: read counts
A Sume bulk queue is completed once every item is terminal, not once every item succeeds. Read counts.failed and each item's status before shipping.
- One bad item in a 100-variant bulk run: 400 and nothing runs
A Sume bulk run checks every item before it creates the queue. One bad row returns 400 invalid_request with details.index, and none of the 100 videos start.
Written by Sume