Burn a rolling headline sequence onto a muted news clip

Put timed headlines on a muted news clip with video-captions cues, a card colour and anchor_ratio. $0.20 per clip up to 60 seconds, no speech needed.

5 min readSume
All posts

To put a rolling headline sequence on a muted news clip, send Video captions a cues array: each cue is text, start and end in seconds. Authored cues skip speech-to-text, so a clip with no speech works, and it costs $0.20 for clips up to 60 seconds.

This is for newsrooms and publishers cutting a silent b-roll package for a feed, where the headline is the content. It does not write the headline for you, and it does not check that the words are accurate.

Why use cues instead of script text?

Speech-based captions need audible speech. A silent clip fails with caption_no_speech and next_action: use_overlay_captions. script_text aligns your wording to speech it hears, so it cannot help here either.

cues (alias segments) are phrase-level overlay cards burned exactly as written at the times you give. script_text, words, cues and segments are mutually exclusive, so send one.

What does the request look like?

Three cards over a 24-second clip, with a dark card behind each and the line placed low in the frame. design merges over the style's own tokens, so only the keys you send change.

import json, os, urllib.request

cues = [
    {"text": "Harbor reopens after storm", "start": 0.5, "end": 7.5},
    {"text": "Ferries run on a reduced timetable", "start": 8.0, "end": 15.5},
    {"text": "Full service expected Friday", "start": 16.0, "end": 23.0},
]
body = {
    "video_url": "https://media.sume.com/artifacts/artf_demo/harbor.mp4",
    "style": "slam",
    "cues": cues,
    "design": {"colors": {"card": "rgba(0,0,0,0.6)"}, "placement": {"anchor_ratio": 0.8}},
}
key = os.environ.get("SUME_API_KEY")
if not key:
    raise SystemExit("set SUME_API_KEY")
req = urllib.request.Request("https://api.sume.com/v1/video-captions",
    data=json.dumps(body).encode(), method="POST",
    headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json",
             "Idempotency-Key": "harbor-headlines-v1"})
print(urllib.request.urlopen(req).read().decode())

The video_url must be a fetchable public HTTPS URL; localhost, private-network, signed or private URLs are rejected. If your footage lives in a private bucket, import it first and see Media inputs. Poll with GET /v1/jobs/:id/status, then read the result, as in Jobs and results.

Which design fields matter for headlines?

Design tokens for a headline look, read 2026-10-02
GroupFieldWhat it changes
colorscardFill behind the line; null draws no card
colorsbase, active, strokeText fill, spoken-word colour, outline
placementanchor_ratioLine centre as a fraction of frame height
placementlandscape_anchor_ratioSame, for landscape frames
phrasingmax_words, max_charsHow a cue wraps into cards

What are the limits to plan around?

Out-of-range numbers are a 400 at request time rather than a wrong render. design is not supported on punch or tiktok-green. Korean copy on a Latin style such as slam is refused with caption_hangul_text_latin_style, so use a Hangul style like black-outline for Korean headlines.

The $0.20 price is a fixed estimate for videos up to 60 seconds, and the docs tell you to confirm it in GET /v1/catalog. Longer clips are not covered by that line, so keep a package to a minute, or split it.

Burning is permanent for that output: there is no toggle for viewers. If a platform shows its own captions, you may get two layers, so keep the on-frame headline short and above the platform's own text zone.

Sources

Related posts

More in Use cases

All Use cases posts

Written by Sume