What to save from a Sume run when batch results expire at 30 days
OpenAI keeps batch output 30 days, Anthropic 29, Gemini 6 weeks. Which Sume run receipt fields to store so your records outlive any vendor retention window.

How long can you read old batch results? It depends on the vendor. The OpenAI Batch guide says output files are deleted 30 days after the batch completes, Anthropic's batch page says results are available for 29 days, and the Gemini Batch API guide says results are kept for 6 weeks (all read 2026-10-04). A Sume run receipt is different: media URLs on media.sume.com are durable, so what you save is a small record, not the files.
Holiday work makes the question practical. A campaign built in October gets audited in January, and the batch that produced it is gone by then.
Retention windows in one table
| Source | Result retention | What you must do |
|---|---|---|
| OpenAI Batch | Output files deleted 30 days after the batch completes | Copy output before day 30 |
| Anthropic Message Batches | Results available for 29 days | Copy results before day 29 |
| Gemini Batch API | Results kept 6 weeks | Copy results inside 6 weeks |
| Sume Format run | Media URLs are durable | Store the receipt fields below |
Reconcile before the window closes
Set a calendar rule shorter than the shortest window: copy any vendor batch output within a week, long before day 29. For a holiday campaign that starts in October, the batch that wrote your scripts is gone by early November, which is still before the season ends.
Reconciliation is a simple join. For every SKU you expected, you should have a stored text result and, for video, a stored run id with a terminal status. Anything missing is either a failure you can still retry or a gap you should know about while the vendor copy still exists.
Sume gives you two ways to rebuild a run record later: GET /v1/format-runs/{run_id}/result for the full receipt once terminal, and the run's own status_url for the small poll payload. If you kept only the run id, the receipt is recoverable.
The small record worth keeping
From each completed run keep the identifiers and URLs, not the bytes. The run id is the key. The receipt's output object holds your schema-shaped result, primary_output_url points at the main file, and artifacts[] lists every produced file with its type and content type. Keep status, the created_at and finish times, and the usage block, remembering that usage is null rather than zero when the numbers could not be read.
For a bulk queue, also keep the queue id, the submitted order of rows, and each item's status and error. There is no list-queues endpoint, so the id and the order are the only way back into a queue.
A failed run belongs in the record too, with its error.code. The reason a video is missing is exactly what an auditor asks in January.
Archive a receipt
The script below reduces a receipt to the fields above and writes one line of JSON per run. It reads a sample receipt inline so you can run it as is.
import json
receipt = {
"id": "run-1", "status": "completed",
"created_at": "2026-10-04T00:00:00Z",
"primary_output_url": "https://media.sume.com/a/clip.mp4",
"output": {"headline": "Gift-ready"},
"artifacts": [{"id": "a1", "type": "video",
"url": "https://media.sume.com/a/clip.mp4", "content_type": "video/mp4"}],
"usage": None,
}
keep = {k: receipt.get(k) for k in
("id", "status", "created_at", "primary_output_url", "output", "usage")}
keep["artifact_urls"] = [a["url"] for a in receipt["artifacts"]]
line = json.dumps(keep, sort_keys=True)
print(line)
assert json.loads(line)["usage"] is NoneWhere the receipt comes from
Either transport gives you the same object. A terminal webhook carries the receipt in payload, byte-identical to GET /v1/format-runs/{run_id}, except that a receipt over 1 MiB arrives with payload: null and an error.result_url to fetch it from. Dedupe on request_id, which equals the run id, so a redelivery does not write a second line.
Sources
Related posts
More in Developers
- isTerminalJobStatus vs isTerminalRunStatus: skipped only ends runs
The Sume SDK has two terminal checks. Jobs end on completed, failed or canceled; runs also end on skipped. Reusing one for both breaks a custom poll loop.
- Seedance 1.5 Pro retires Nov 11: pin a live Sume model id
ElevenLabs says ByteDance retires Seedance 1.5 Pro on Nov 11, 2026. Pin an id Sume's video catalog lists today and verify its limits first.
- Seedance 2.5 720p on fal, 1080p on Sume: read the catalog
fal lists Seedance 2.5 Image to Video at up to 720p and 30 seconds. Sume docs list seedance-2.5 at 4-30 s and 480p/720p/1080p. Check the catalog before pinning.
- Shopify rejects file names ending in thumb, icon or large
Shopify file uploads reject names ending in pico, icon, thumb, testing, small, compact, medium, large or grande. A Python rename step for batch outputs.
Written by Sume