Luma Ray 2 API parameters: keyframes, loop and callback_url
Luma's video docs list ray-2 and ray-flash-2 with keyframes, loop, concepts and callback_url. Here is each field mapped to the Sume /v1/videos request.

Luma's video generation docs, read 2026-10-03, list two models, ray-2 and ray-flash-2, with resolutions from 540p to 4k and request fields for keyframes, loop, concepts and a callback_url. On Sume the same jobs map to POST /v1/videos with frame_images, a callback_url and a catalog model id, and you read the supported ranges from GET /v1/videos/models instead of from a doc page.
One caveat from the research: Luma's docs page lists Ray 2 only and may lag newer Ray releases, so treat the table below as the state of that page on the read date.
What the Luma page says
The facts below are taken from the Luma docs page and nothing else.
| Item | What the page lists |
|---|---|
| Models | ray-2 and ray-flash-2 |
| Resolutions | 540p, 720p, 1080, 4k |
| Request features | keyframes, loop, concepts, callback_url |
| Extend | Only for videos Luma generated |
| Image inputs | Must be CDN URLs |
Mapping each field to Sume
Sume follows the OpenRouter video wire on /v1/videos, so a few Luma ideas have a direct counterpart and a few do not.
- Keyframes: send
frame_imageswithframe_typeset tofirst_frameorlast_frame. Each model lists which values it accepts insupported_frame_images. - Callback: pass
callback_url. It must be HTTPS, and Sume posts its standard job webhook envelope when the job reaches a terminal state. - Image inputs: Sume wants public HTTPS URLs, and a URL Sume cannot fetch returns an error such as
image_not_fetchablerather than a silent skip. - Loop and concepts: the Sume docs list no
looporconceptsfield on/v1/videos, so describe a seamless loop or a camera move in the prompt instead. - Extend: the docs describe no extend endpoint on this route. Chain a new job from a chosen frame if you need a longer shot.
Webhook or polling
Luma exposes a callback_url; Sume does too, and the webhooks guide says to keep polling as a fallback because delivery is an optimization. Sume retries a failed delivery up to 10 times, 30 seconds apart by default, with a 10 second timeout per attempt. Use the job_id as your idempotency key, since a redelivery repeats the same event.
A submit that uses both mechanisms looks like this:
curl -X POST https://api.sume.com/v1/videos \
-H "Authorization: Bearer $SUME_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ray2-port-001" \
-d '{
"model": "sume/auto",
"prompt": "Slow push-in on a ceramic mug, steam rising, soft window light",
"duration": 5,
"resolution": "720p",
"aspect_ratio": "16:9",
"callback_url": "https://example.com/hooks/sume"
}'Verify the callback
Sume signs the raw body with HMAC SHA 256 over <timestamp>.<raw_body> and sends x-sume-webhook-timestamp and x-sume-webhook-signature: sume-v1=<hex>. This verifier refuses an empty secret and a stale timestamp.
import hashlib, hmac, time
def verify(raw_body: bytes, timestamp: str, header: str, secret: str, tolerance=300) -> bool:
if not secret:
raise ValueError("empty webhook secret")
try:
ts = int(timestamp)
except ValueError:
return False
if abs(int(time.time()) - ts) > tolerance:
return False
signed = f"{ts}.".encode() + raw_body
digest = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
expected = "sume-v1=" + digest
ok = False
for entry in header.split(","):
if hmac.compare_digest(entry.strip(), expected):
ok = True
return okPorting checklist
Work through the list in order before you switch traffic.
- Replace every CDN image URL with a public HTTPS URL that Sume can fetch without cookies.
- Move keyframes to
frame_imagesand confirm the model lists them insupported_frame_images. - Add an
Idempotency-Keyto every paid submit so a network retry cannot create a second job. - Store the Sume
job_idbeside your own record, and use it as the idempotency key for webhook handling. - Keep a polling fallback running, because a callback can be refused ten times and the job still finishes.
- Test one failure on purpose, for example an unreachable image URL, and confirm your handler reads the public error.
What to check before porting
Read supported_resolutions, supported_durations and supported_frame_images for the model you pin, because limits are not uniform across the catalog. If you do not want to pin one, model: "sume/auto" lets Sume pick the family, and the job echoes sume/auto. Sume bills workspace USD balance reserved at submit, at provider list times 1.25, and usage.cost on the poll response is the billable amount.
Sources
Related posts
More in Comparisons
- Midjourney has no public API: comparable control in a pipeline
Midjourney's 10/1 alpha adds a pinnable --exp setting and edits that keep aspect ratio. What to use when you need that kind of control from code.
- MiniMax H3 vs H3-Max limits: the MiniMax page next to Sume's catalog
MiniMax lists H3 at 4 to 15 s and H3-Max at 5 to 15 s with different resolutions. Sume's catalog states its own ranges. Side by side, with the file-size limits.
- Pika API Club: 100+ models at reduced pricing, questions to ask first
Pika's API Club (Aug 5) offers 100+ models at reduced pricing, and the Sep 17 relaunch adds audio models. Seven questions to ask an aggregator.
- Capacity fallbacks: Replicate's model swap vs pinning on Sume
Replicate lists a model falling back to another at capacity. On Sume you pin a model or send sume/auto, and a capacity error is retried with the same key.
Written by Sume