Veo videos vanish after 2 days: copy to Cloud Storage and expire them
Google keeps Veo output on its server for 2 days. Copy each clip to your own bucket, then let a Cloud Storage lifecycle rule delete old copies on a schedule.

Veo 3.1 videos are stored on Google's server for 2 days and then removed, so download each clip right away and keep your own copy. A Cloud Storage lifecycle rule with an age condition and a Delete action will then expire your copies after the number of days you choose.
What Google keeps and what Sume keeps
Google's Veo guide says generated videos are stored for 2 days, after which they are removed, and that extended videos have the same 2-day window. Sume's media inputs doc says Sume mirrors generated outputs into Sume-owned media URLs before it shows them in public results, and that integrations must store the Sume URL and not raw provider URLs. The docs do not state a retention period for those artifacts, so copy anything you must keep long term.
| System | What the docs say | Your action |
|---|---|---|
| Veo on Gemini API | Stored 2 days, then removed | Download within hours |
| Sume artifacts | Mirrored to Sume-owned URLs, no retention period stated | Store the Sume URL, copy what you must keep |
| Cloud Storage lifecycle | Rules act on age in days | Set Delete after N days |
| Lifecycle timing | Actions can lag, config changes can take up to 24 hours | Do not rely on exact minutes |
The lifecycle rule
Google's lifecycle docs list conditions such as age (days since creation), matchesPrefix and matchesSuffix, and actions such as Delete and SetStorageClass. Delete makes objects soft-deleted by default, retained for seven days unless soft delete is off. Cloud Storage inspects objects regularly, so there can be a lag between a rule becoming true and the action.
import json
config = {
"rule": [{
"action": {"type": "Delete"},
"condition": {"age": 30, "matchesPrefix": ["sume-clips/"]},
}]
}
with open("lifecycle.json", "w") as f:
json.dump(config, f, indent=2)
print("wrote lifecycle.json")
print("apply: gcloud storage buckets update gs://YOUR_BUCKET "
"--lifecycle-file=lifecycle.json")
Why a prefix
Put clips you want to expire under one prefix, such as sume-clips/, and keep finals under another. The rule above only touches the first. Choose the age to fit your review cycle: if a client needs a month to approve, 30 days is a safe floor, and an age of 2 days would copy Google's window without any benefit.
Operational notes
These details come from Google's lifecycle page, and they matter because a deletion rule is hard to undo. A wrong prefix can remove files you meant to keep.
- Name objects with the Sume job id, so a clip and its record can be matched.
- Test the rule on a small prefix first, since lifecycle changes can take up to 24 hours to apply.
- Remember that deleted objects stay soft-deleted for seven days by default.
- Use a storage class change only for large files, because Class A operations cost money on small ones.
Download first, then archive
For Sume jobs, poll GET /v1/videos/{id} until completed, then fetch unsigned_urls[0] with your key and write it to your bucket. Record the job id and usage.cost beside the object, as in the Videos guide. That gives you a clip and its cost record in your own storage, on your own expiry schedule.
Sources
Related posts
More in Integrations
- Webflow Assets API lists no audio types: where a Sume track goes
Webflow's asset docs name image, document and Lottie types, not audio. Keep the Sume mp3 on its media.sume.com URL and store that link in a CMS Link field.
- WordPress media_handle_sideload for a Sume music mp3 attachment
Download the Sume artifact URL with download_url(), then media_handle_sideload() it into the Media Library. It returns an attachment id or a WP_Error.
- X media upload APPEND: 5 MB chunks, and how to split a Sume MP4
The X API v2 APPEND step takes chunks of at most 5 MB. Count the segments for a Sume MP4 with a short script before you upload to the initialize endpoint.
- X media upload processing_info states: poll until succeeded
After FINALIZE on the X API v2, processing_info moves from pending to in_progress to succeeded or failed. Poll using check_after_secs, then post the Sume video.
Written by Sume