xAI batch video URLs expire in 1 hour: size the download worker

xAI's release notes say image and video URLs in batch results expire after 1 hour. How many parallel downloads you need, and how Sume's durable URLs differ.

5 min readSume
All posts

If xAI's batch endpoint now generates video, how long do you have to save the files? One hour. The xAI release notes (read 2026-10-04) say the Batch API now supports image generation, image editing and video generation in addition to chat completions, and that image and video URLs in batch results expire after 1 hour. The same page does not give a per-file size or a typical batch duration, so those numbers are yours to measure.

The consequence is a design rule: the process that notices a finished batch must also be the process that downloads every file, quickly, before the clock runs out. On Sume the equivalent step does not exist, because the docs describe media URLs on media.sume.com as durable URLs that do not expire.

Size the downloader before launch

Take a batch of N videos, an average file size S in megabytes, and the sustained download speed D in megabytes per second you can really get from your server. The serial download time is N times S divided by D. If that number is near an hour, you need parallel workers and a margin, because one failed download needs a retry inside the same window.

Measure S and D on a sample of ten files from a trial batch. Do not take them from a vendor page; this post has none to offer. The script below turns your measurements into a worker count that finishes in half the hour, leaving the other half for retries.

import math

N = 1000         # videos in the batch
S = 25.0         # average MB per file, measured on a sample
D = 12.0         # MB per second per worker, measured
WINDOW = 3600    # seconds the URLs stay valid
BUDGET = WINDOW / 2

serial = N * S / D
workers = max(1, math.ceil(serial / BUDGET))
print(f"serial download: {serial / 60:.1f} min")
print(f"workers for half the window: {workers}")
assert workers * D * BUDGET >= N * S

What changes on Sume

A Sume run ends with a receipt whose output, artifacts[] and primary_output_url point at durable media.sume.com URLs. Reading the receipt is a plain GET to result_url, and a delivered webhook carries the same receipt, so there is no race between a finished job and an expiring link. You can store the URL and fetch the file when a customer needs it.

That does not remove the need to track queue progress. A bulk queue is completed when every item is terminal, and you still branch on counts.failed and counts.canceled. It only removes the one-hour deadline from the success path.

Operational rules for the one-hour window

Start the download clock from the moment you first see the batch finished, not from your last poll. Poll often enough that the lag is a small fraction of the hour, and log the time you first saw each result URL so a late job is visible in your own data.

Download in the order the batch returned, write each file to storage you control, and record success per file before you mark the batch done. A batch with one expired URL is a batch that needs a regeneration, so keep the original request lines available.

The same release notes list a Files API change that supports public URLs with auto-expiry; the page is the place to read the current range before you rely on it. Whatever you pick, copy outputs into your own storage rather than treating a vendor URL as an address you keep.

Side by side

Result URL lifetime, xAI release notes and Sume Runs docs read 2026-10-04
xAI Batch APISume Format run
Video generation in batchSupported, per the release notesFormat run; bulk queue holds 1 to 100 items
Result URL lifetimeImage and video URLs expire after 1 hourmedia.sume.com URLs are durable and do not expire
What to do on successDownload everything inside the hourStore the URL from the receipt
Retry windowInside the same hourNew run with a new idempotency key, or previous_run_id

Sources

Related posts

More in Comparisons

All Comparisons posts

Written by Sume