How long does a Sume TTS audio_url last? Archive voiceovers anyway
Sume TTS returns a media.sume.com artifact URL. What the docs and code state about expiry, what they do not, and a Python snippet that saves each voiceover.

Sume TTS mirrors each voiceover to a public media.sume.com artifact URL, and none of the TTS or job-result docs I read states a retention period for it. The only explicit "does not expire" wording is on the Action-run media file schema, a different surface, and the media-import schema says retention is not yet defined. So treat the URL as the delivery link and keep your own copy of any voiceover you cannot afford to regenerate.
Read on 2026-10-03: the Sume API reference (TTS, artifact, media-import and Action media schemas), the Media inputs docs page and the artifact package defaults in the Sume repository.
What is verified about the URL?
Completed TTS jobs expose mirrored audio artifacts. The artifact schema calls the URL a public Sume CDN URL with visibility: public_by_link, and says clients must not parse the path. The artifact package defaults to Cache-Control: public, max-age=31536000, immutable, which is a one-year cache instruction, not a retention promise.
| Source | Statement |
|---|---|
| TTS artifact (PublicArtifact) | Public CDN URL, public_by_link; no expiry or retention stated |
| Action run media file (SumeMediaFile) | Served immutable; durable URLs do not expire; expires_at is null |
| Media import | Retention and expiry not yet defined |
| Cache-Control default | public, max-age=31536000, immutable |
Should you archive voiceovers?
Yes, for anything you would pay to regenerate or that a contract requires you to keep. The cost of a copy is one download. Also store the transcript, voice id and settings next to the file: TTS is billed at $0.0475 per 1,000 characters before the agent fee, so a regenerated take is a second charge.
Because the URL is public by link, anyone holding it can fetch the file. Do not put private scripts in voiceovers you share by URL.
Download and store the file
This submits a short line, waits for the job and saves the MP3 with a SHA-256 beside it. Set SUME_VOICE_ID.
import hashlib, os, time, requests
API = "https://api.sume.com"
AUTH = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
body = {"transcript": "Hello from Sume TTS.",
"voice": {"id": os.environ["SUME_VOICE_ID"]}}
r = requests.post(f"{API}/v1/tts-1.0/generate", json=body,
headers={**AUTH, "Idempotency-Key": "vo-archive-001"})
r.raise_for_status()
job = r.json()["data"]
while True:
s = requests.get(job["status_url"], headers=AUTH).json()["data"]
if s["terminal"]:
break
time.sleep(s.get("next_poll_after_seconds") or 3)
res = requests.get(job["result_url"], headers=AUTH).json()["data"]["result"]
url = next(a["url"] for a in res["artifacts"] if a["type"] == "audio")
audio = requests.get(url).content
open("voiceover-001.mp3", "wb").write(audio)
print(url, hashlib.sha256(audio).hexdigest())What if the file is gone later?
Regenerate from the stored transcript and voice, or restore your archived copy. Either way, the stored copy is what keeps a published video's audio stable.
Sources
Related posts
More in Developers
- How many characters is one minute of TTS audio? 1,200 s math
A vendor rule of thumb says a minute of speech is 750-800 characters. Here is what that means for a 1,200-second Sume TTS job and its 20,000-char cap.
- How Sume Bills a Failed AI Video Job: Reserve, Refund, Retry
A video job reserves its price at submit and refunds on failure. See what Idempotency-Key does on a retry and when to download before storage expires.
- httpx MockTransport: test a Sume poll loop with no network
Pass httpx.MockTransport to httpx.Client to feed a Sume status poller canned replies, assert it stops on terminal and honors next_poll_after_seconds.
- Idempotency-Key over 255 characters: hash long business keys
Sume accepts Idempotency-Key values up to 255 characters. Keep readable keys when short and fall back to a prefixed SHA-256 for long ones. Runnable Python.
Written by Sume