Skip to content
lumalabs.ai

Migrate legacy Ray models

Move Ray 3, Ray 2, Ray 2 Flash, Ray 2 Relaxed, Ray 3 Reference, and Ray 3 Refiner integrations to Ray 3.2 on the Luma Agents API.

Move legacy Luma video integrations to Ray 3.2 on the Luma Agents API. This guide is for API customers using any of these retiring models:

  • Ray 3
  • Ray 2
  • Ray 2 Flash
  • Ray 2 Relaxed
  • Ray 3 Reference
  • Ray 3 Refiner

If you received a deprecation notice, use the retirement date in that message as the cutoff for your account. Legacy requests will continue to work during the notice period, but begin migrating early enough to validate your production workflows before you cut over.

The legacy API used model variants and separate request shapes to express intent. The Luma Agents API gives you one model and a small set of composable primitives:

DecisionLegacy approachLuma Agents API
Where to send workSeparate video and modify routesPOST https://agents.lumalabs.ai/v1/generations
Which model to callRay 3, Ray 2, Flash, Relaxed, Reference, or Refinermodel: "ray-3.2"
What operation to runImplied by model or routetype: "video", "video_edit", or "video_reframe"
What media to useRoute-specific media and keyframes shapessource, video.start_frame, video.end_frame, or video.*.keyframes
How to tune outputTop-level fields and model variantsCommon settings under video; edit settings under video.edit
How to get the resultAsync generation objectSubmit once, poll GET /v1/generations/{id}, download output[].url

Choose the primitive that matches your job

Section titled “Choose the primitive that matches your job”
What you want to dotypeCore inputsStart here
Generate from textvideopromptText-to-video
Animate one imagevideovideo.start_frameImage-to-video
Interpolate between two imagesvideovideo.start_frame + video.end_frameImage-to-video
Direct a new clip with several imagesvideovideo.keyframes + video.keyframe_indexesMulti-keyframe generation
Continue a completed Luma videovideoOne generation_id in video.start_frame or video.end_frameExtend a video
Restyle, refine, or transform a videovideo_editsource + optional video.editVideo editing
Pin the look of an edit at exact momentsvideo_editsource + video.edit.keyframes + indexesEdit keyframes
Change a video’s aspect ratiovideo_reframesource + target aspect_ratioVideo reframing
  1. Create an API key in the Luma developer dashboard. New keys begin with luma-api- and are shown only once.
  2. Store the key on your server as LUMA_AGENTS_API_KEY. Do not expose it in browser or mobile code.
  3. Point your client to https://agents.lumalabs.ai/v1.
  4. Confirm ray-3.2 access with the Playground, then copy its generated cURL for your first request shape.
  5. Port one workflow at a time using the primitive matrix above.
Terminal window
export LUMA_AGENTS_API_KEY="luma-api-..."
curl -X POST https://agents.lumalabs.ai/v1/generations \
-H "Authorization: Bearer $LUMA_AGENTS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "ray-3.2",
"type": "video",
"prompt": "A slow dolly through a greenhouse at sunrise",
"aspect_ratio": "16:9",
"video": {
"resolution": "720p",
"duration": "5s"
}
}'

The response is a generation object in queued state. Save its id; you use that same id to poll, edit, extend, or reframe the result.

Do not look for one new model name per retired model. Every row below uses model: "ray-3.2"; the request’s type, media references, and controls now express the difference.

Retiring model or workflowNew request shapeWhat changed
Ray 3type: "video"Use the standard generation primitive for text-to-video and image-to-video.
Ray 2type: "video"Move output controls under video and re-evaluate prompts and output quality.
Ray 2 Flashtype: "video"There is no separate Flash model identifier. Benchmark Ray 3.2 latency and adjust timeouts and concurrency for your account.
Ray 2 Relaxedtype: "video"There is no separate Relaxed model identifier. Preserve your creative intent in the prompt and anchor frames.
Ray 3 Referencetype: "video" or "video_edit" with keyframesUse generation keyframes to direct a new clip, or edit keyframes to direct changes to an existing clip.
Ray 3 Refinertype: "video_edit" with sourceStart with video.edit.auto_controls: true; add strength, per-signal controls, or keyframes only when you need more control.
Legacy field or behaviorNew field or behaviorMigration note
POST .../generations/videoPOST /v1/generations + type: "video"Text-to-video, image-to-video, interpolation, and extend share one type.
POST .../generations/video/modifyPOST /v1/generations + type: "video_edit"The route no longer selects the operation.
Any retiring model identifiermodel: "ray-3.2"Use this exact public wire value.
Dedicated HDR modelvideo.hdr: trueHDR is a control, not a model. See video generation constraints.
Top-level resolution, duration, loopvideo.resolution, video.duration, video.loopCommon video settings now live together.
keyframes.frame0video.start_frameDrop the old type discriminator.
keyframes.frame1video.end_frameSet both start and end images to interpolate.
Generation keyframe { "type": "generation", "id": "..." }{ "generation_id": "..." }A single generation ref in start_frame extends forward; one in end_frame extends backward.
Modify media.urlsource: { "url": "...", "media_type": "video/mp4" }Or use source.generation_id / source.file_id.
Modify modevideo.edit.strengthValues are adhere_13, flex_13, and reimagine_13.
callback_urlPoll GET /v1/generations/{id}The Agents API result flow is submit, poll, download.
// Legacy
{
"model": "ray-3",
"prompt": "A fox runs through fresh snow",
"resolution": "720p",
"duration": "5s",
"aspect_ratio": "16:9"
}
// Luma Agents API
{
"model": "ray-3.2",
"type": "video",
"prompt": "A fox runs through fresh snow",
"aspect_ratio": "16:9",
"video": {
"resolution": "720p",
"duration": "5s"
}
}

Before and after: refine an existing video

Section titled “Before and after: refine an existing video”
// Legacy modify/refiner request
{
"model": "ray-3",
"prompt": "Transform the scene into moonlit 35mm film footage",
"media": { "url": "https://example.com/source.mp4" },
"mode": "flex_2"
}
// Luma Agents API
{
"model": "ray-3.2",
"type": "video_edit",
"prompt": "Transform the scene into moonlit 35mm film footage",
"source": {
"url": "https://example.com/source.mp4",
"media_type": "video/mp4"
},
"video": {
"edit": {
"auto_controls": true
}
}
}

Start edits in automatic mode. If you need predictable source adherence, replace auto_controls with a strength preset. For precise creative direction, add keyframes at specific source-frame indexes.

The same reference shapes are reused across generation, editing, and reframing. Choose the form that best matches where the media already lives:

ReferenceUse whenShape
Hosted mediaThe asset is available at a public URL{ "url": "https://...", "media_type": "video/mp4" } for source video
Uploaded fileYou want to upload once and reuse the asset{ "file_id": "..." } from the Files API
Inline dataThe asset is small and cannot be hosted{ "data": "<base64>", "media_type": "video/mp4" }
Prior Luma resultThe asset came from a completed generation on the same API client{ "generation_id": "..." }

Not every reference form is valid in every position. The linked generation, editing, and reframing guides list the exact combinations. As a rule of thumb, use source for the video being changed and keyframe fields for images that direct the result.

POST /v1/generations returns immediately. Poll the returned id until state is completed or failed:

Terminal window
GENERATION_ID="<id-from-post-response>"
curl -H "Authorization: Bearer $LUMA_AGENTS_API_KEY" \
"https://agents.lumalabs.ai/v1/generations/$GENERATION_ID"
StateMeaningWhat your integration should do
queuedAccepted and waiting for capacityContinue polling with backoff.
processingGeneration is runningContinue polling.
completedOutput is readyDownload each output[].url.
failedThe job did not completeLog failure_code, failure_reason, and X-Request-Id; retry only when the error is transient.

Output URLs expire after one hour. Poll the generation again to mint a fresh URL if needed.

Use this checklist for each production workflow:

  • Inventory every call using a retiring model, including background jobs and rarely used fallback paths.
  • Group calls by intent: generate, edit/refine, extend, or reframe.
  • Port each group to its new type and request shape.
  • Run representative prompts and media through the Playground.
  • Compare output quality, latency, failure handling, and cost with your current production baseline.
  • Update polling deadlines and concurrency handling; do not carry Ray 2 Flash timing assumptions forward.
  • Confirm your integration records generation id, state, failure_code, and X-Request-Id.
  • Route a small percentage of production traffic to the new API, then ramp up while watching errors and latency.
  • Move all traffic before the retirement date in your deprecation notice, then remove legacy model identifiers and fallback code.
SymptomLikely causeFix
Unknown modelSent a retired model identifierSend model: "ray-3.2".
Type is not supported for modelReused an image type or omitted the video operationUse video, video_edit, or video_reframe from the primitive matrix.
Video options have no effect or fail validationLeft output fields at the top levelMove them under video.
Source URL is rejectedOmitted its MIME typeAdd source.media_type, such as video/mp4.
Edit source is rejected for durationSource is longer than 18 secondsTrim it to 18 seconds or shorter. Reframe sources must be 10 seconds or shorter.
A completed generation cannot be referencedIt belongs to another API client or is not completeUse a completed generation owned by the same client, or pass a URL / uploaded file instead.
Client waits foreverPolling recognizes only the old lifecycle valuesStop on completed or failed and enforce a deadline.

If you need help planning your cutover or meeting the timing in your deprecation notice, email support+luma-agents-api@lumalabs.ai. For request-shape or runtime issues, include:

  • the retiring model or workflow you are replacing;
  • a redacted old request and new request;
  • the new generation id and X-Request-Id;
  • the HTTP status, failure_code, and failure_reason.
  • Video generation — text, image, multi-keyframe, extend, loop, and HDR
  • Video editing — source media, automatic controls, strength, advanced controls, and keyframes
  • Video reframing — target aspect ratios and source placement
  • Files API — upload media once and reference it by file_id
  • Error handling — HTTP errors, generation failures, and retry guidance
  • Pricing — current Ray 3.2 rates and Provisioned Throughput