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.

5 min readSume
All posts

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

Result retention, vendor pages and Sume Runs docs read 2026-10-04
SourceResult retentionWhat you must do
OpenAI BatchOutput files deleted 30 days after the batch completesCopy output before day 30
Anthropic Message BatchesResults available for 29 daysCopy results before day 29
Gemini Batch APIResults kept 6 weeksCopy results inside 6 weeks
Sume Format runMedia URLs are durableStore 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 None

Where 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

All Developers posts

Written by Sume