Replay a sume/auto video submit with one key, assert one job
Submit model sume/auto twice with the same Idempotency-Key and assert the same job id and the same route. Why a replay is safe and why Sume hides the family.

When you send model sume/auto to /v1/videos, Sume picks the model family for you. A retry with the same Idempotency-Key must not pick again, and the docs say it does not: resolution is a pure function of the normalized request and the catalog version, so a replay gets the same price and the same route. The Python test below proves it for your key by submitting twice and asserting one job id.
What the test checks
The script posts one body twice with the key auto-replay-check-001. It asserts that both responses carry the same id, and that the model field of the response is sume/auto, which is the only name Sume reports. Sume never discloses which family served the request, so the test must not try to infer it from the output.
Run it only on a real key you are willing to spend on: the first submit is a paid job. Keep the clip short; the body uses 5 seconds at 9:16. The reserved amount at submit is the provider list price times 1.25 for the routed family, which you cannot know beforehand, so treat the first run as a small experiment and read usage.cost from the completed job.
| Question | Answer |
|---|---|
| Same key, same body | The original job is returned; no second job |
| Does the route change on replay? | No: price and route come from the normalized request and the catalog version |
| What model name is reported? | sume/auto, in submit and poll responses |
| Which family ran? | Not disclosed by Sume |
| Same key, different body | 409 idempotency_conflict |
The Python test
The helper uses urllib, so there is nothing to install. A non-2xx answer raises HTTPError, which is the right failure for a test.
import json, os, urllib.request
def submit(body, key):
req = urllib.request.Request(
"https://api.sume.com/v1/videos", json.dumps(body).encode(),
{"Authorization": "Bearer " + os.environ["SUME_API_KEY"],
"Content-Type": "application/json", "Idempotency-Key": key})
with urllib.request.urlopen(req) as r:
return json.load(r)
body = {"model": "sume/auto", "prompt": "Vertical UGC-style clip of a desk lamp turning on",
"aspect_ratio": "9:16", "duration": 5}
first = submit(body, "auto-replay-check-001")
again = submit(body, "auto-replay-check-001")
assert first["id"] == again["id"], "replay created a second job"
assert again["model"] == "sume/auto"
print("same job:", first["id"], "model:", again["model"])Where this matters
The case that hurts is a timeout in your client after Sume accepted the job. Without a key the retry may create a second paid job and, with auto routing, possibly on a different family. With a key the retry returns the first job.
Do not reuse the same key to ask for a different clip; a different payload under a used key is a 409 idempotency_conflict. Build keys per intent, as in the body-hash post, and store them with the job id.
After the assertion passes, poll GET /v1/videos/{id} for the job as usual. The poll response reports the same sume/auto name and, once the job completes, a usage.cost that is the Sume billable amount. That number is what you compare across runs if you are deciding between auto routing and a pinned model: run the same prompt once on auto and once on a catalog id and read both costs.
- Pin a model with a catalog id when you need a known price in advance.
- Use sume/auto when you want Sume to choose and accept that the family is not disclosed.
- Keep the test out of CI unless CI has a spending budget.
Sources
Related posts
More in Developers
- Resume a Sume job wait after SumeJobTimeoutError in TypeScript
A 30-second Seedance 2.5 clip can outlast one waitForJob call. Call it again with the same job id on timeout or a transient read error. Never resubmit.
- Resume polling Sume video jobs after a restart with a sqlite ledger
Write the job id and Idempotency-Key to sqlite before anything else can crash, then resume polling open jobs on start. Python standard library only.
- Ruby Net::HTTP: Gemini Omni Flash 1.1 vertical 6 s clip, $0.75
Ruby standard library only: submit a 6-second 9:16 Gemini Omni Flash 1.1 clip to Sume ($0.75 at 720p) and poll to completion. Prices at four resolutions.
- Run receipt micros: 5,000,000 is $5.00 and 240,000 is $0.24
Sume run receipts report spend in USD micros. How to convert the cap and billable fields to dollars, and why GET /v1/usage stays the billing ledger.
Written by Sume