Veo 3.1 deletes clips after 2 days: archive them, and the Sume path

Google keeps Veo 3.1 videos on its server for 2 days, and extending a clip resets the timer. Download on completion. Veo 3.1 is not in the Sume catalog.

4 min readSume
All posts

Veo 3.1 deletes generated videos 2 days after they are made. Google's Veo guide says: "Generated videos are stored on the server for 2 days, after which they are removed." A pipeline that stores only the Google file reference will lose clips on day 3, so download each clip when the job completes and keep your own copy.

Sume does not carry Veo 3.1. The Sume video catalog has one Google video model, gemini-omni-flash-1.1, and it follows a different download path (below).

What Google documents for Veo 3.1

The 2-day window is the only retention figure in the Veo guide. Extension is the one feature that moves it.

Veo 3.1 storage and lifecycle facts, read 2026-10-05
ItemDocumented valueSource
Server-side storage2 days, then removedVeo guide
Extended videosTimer resets on the extended videoVeo guide
Extension limitsVeo 3.1 and 3.1 Fast only; adds 7 seconds per call, up to 20 times; 720p onlyVeo guide
Preview ids endveo-3.1-generate-preview, veo-3.1-fast-generate-preview and veo-3.1-lite-generate-preview shut down October 22, 2026Deprecations page

The archive pattern

Treat the Google file as a handoff, not storage. When the job finishes, copy the bytes to your own bucket in the same worker, and save your own object key in your database. Do not save only the Google reference.

If you extend a clip, Google resets the timer on the extended video. Still archive every clip you want to keep, including the intermediate ones, as you make them.

The same step on Sume

Sume video jobs are asynchronous. You submit to POST /v1/videos, poll GET /v1/videos/{id}, and read unsigned_urls when the status is completed. Each URL is the content endpoint, GET /v1/videos/{id}/content?index=0. The Sume docs send the API key as a Bearer header on that call, and the script below does the same.

import asyncio, os, requests

H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}

async def main():
    job_id = "job_01HXYZ"  # the id from POST /v1/videos
    url = f"https://api.sume.com/v1/videos/{job_id}"
    while True:
        r = await asyncio.to_thread(requests.get, url, headers=H)
        job = r.json()
        if job["status"] == "completed":
            break
        if job["status"] in ("failed", "cancelled"):
            raise SystemExit(job.get("error", job["status"]))
        await asyncio.sleep(30)
    clip = await asyncio.to_thread(requests.get, job["unsigned_urls"][0], headers=H)
    with open(f"{job_id}.mp4", "wb") as f:
        f.write(clip.content)

asyncio.run(main())

What differs between the two

The Sume docs do not state how long a generated clip stays available. The docs do say that expired is a status in the enum for wire compatibility, but Sume does not expire jobs now, so the API never emits it. Treat the retention window as unspecified and copy the file to your own storage in either case.

Retention and download comparison, read 2026-10-05
QuestionVeo 3.1 on the Gemini APISume /v1/videos
Is the model available?Yes, three preview ids until October 22, 2026No. Use gemini-omni-flash-1.1
Where do the bytes come from?Google server, 2-day windowGET /v1/videos/{id}/content?index=0
Documented retention2 daysNot stated in the docs
expired statusNot applicableIn the enum, never emitted

Sources

Related posts

More in Developers

All Developers posts

Written by Sume