Luma API callback_url vs Sume callback_url: signing and retries
Luma's video API takes a callback_url, and so does Sume's /v1/videos. What Sume's callback is signed with, how often it retries, and a Python verifier.

Both APIs accept a callback_url, but the guarantees differ. On Sume, the URL must be public HTTPS, the delivery is signed with HMAC SHA 256 over the timestamp and raw body, and a failed delivery is attempted up to 10 times in total. The Luma video generation docs, read on 2026-10-03, list callback_url among the generation parameters without the details covered here.
What Luma documents
The Luma page lists the models ray-2 and ray-flash-2, resolutions of 540p, 720p, 1080, and 4k, and parameters for keyframes, loop, concepts, and callback_url. It says extension works only for generated videos and that images must be CDN URLs. The page lists Ray 2 only, so it may lag newer Luma models.
What Sume documents
The Sume video docs say callback_url must be HTTPS and that Sume POSTs once the job reaches a terminal state. The webhooks docs give the rest.
| Item | Behavior |
|---|---|
| URL rule | Public HTTPS only; localhost and private networks are rejected |
| Events | job.completed, job.failed, job.canceled; terminal only |
| Signature | x-sume-webhook-signature: sume-v1=<hex> over <timestamp>.<raw_body> |
| Timestamp header | x-sume-webhook-timestamp; reject outside a replay window (five minutes suggested) |
| Retries | Up to 10 attempts, fixed 30 s spacing by default, 10 s timeout per attempt |
| Idempotency | Use job_id as the key on your side |
Verify the callback in Python
The verifier below refuses an empty secret, checks the timestamp window, and compares every sume-v1= entry, since the header can carry two during a secret rotation. Pass the raw request body bytes, not a re-serialized JSON object.
import hashlib
import hmac
import time
def verify(raw_body: bytes, timestamp: str, signature_header: str, secret: str, tolerance: int = 300) -> bool:
if not secret:
return False
try:
ts = int(timestamp)
except ValueError:
return False
if abs(int(time.time()) - ts) > tolerance:
return False
digest = hmac.new(secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256).hexdigest()
expected = f"sume-v1={digest}"
matched = False
for entry in signature_header.split(","):
if hmac.compare_digest(entry.strip(), expected):
matched = True
return matchedChoosing between callback and polling
Callbacks save polling traffic and give faster notice, but they need a public HTTPS endpoint that is always up. Polling needs no public endpoint, which suits scripts and local development, but wastes calls on long jobs.
Many integrations use both: a callback for the fast path and a slow poll as a backstop. The Sume video docs suggest a polling interval around 30 seconds for video, since jobs commonly take from 30 seconds to several minutes, depending on the model and parameters.
- Server with a stable HTTPS endpoint: callback plus slow poll.
- Script or notebook: poll only.
- Both: dedupe on
job_id. - Never trust an unsigned callback.
Keep polling as a backstop
Do not rely on a callback alone. The Sume docs say delivery is an optimization, never the only recovery path, and recommend keeping status polling available. The same rule applies to any vendor callback, Luma's included. Keep a poll loop that wakes up for jobs with no terminal event after your own deadline.
Sources
Related posts
More in Developers
- MCP 2026-07-28 deprecations: SSE, sampling, roots, logging checklist
MCP 2026-07-28 deprecates Roots, Sampling and Logging and reclassifies HTTP+SSE as Deprecated, with 12 months of notice. A checklist for media servers.
- MCP OAuth without DCR: client ID metadata documents and issuer checks
MCP 2026-07-28 deprecates dynamic client registration for Client ID Metadata Documents and requires clients to validate iss. What it means for Sume.
- Python MCP SDK 2.3 subscriptions=False: a Sume wrapper that pulls
MCPServer(subscriptions=False) turns off push subscriptions in the Python SDK. A wrapper over Sume jobs can do without them by waiting in bounded slices.
- Python MCP SDK v1 now gets security fixes only: use v2 for new clients
The Python MCP SDK v1.x line gets security fixes only; v2 added MRTR and the 2026-07-28 spec. What that means when you connect a client to Sume's hosted MCP.
Written by Sume