Luma Ray 3.2 Video Reframing is a fast AI video reframing model that changes an existing video’s aspect ratio and fills the newly exposed canvas from a prompt while preserving the source footage. Ready-to-use REST inference API for aspect ratio conversion, social media resizing, cinematic reframing, video outpainting, creator content, advertising creatives, and professional video editing workflows with simple integration, no coldstarts, and affordable pricing.
Bereit
$0.06pro Durchlauf·~16 / $1
Outpaint the image to a 3:4 portrait aspect ratio suitable for mobile viewing, naturally extending the surrounding scene while matching the original lighting, perspective, and background details.
Luma Ray 3.2 Video Reframing changes the aspect ratio of an existing video while preserving the original footage. Upload a source clip, choose a target size, and describe what should appear in the newly exposed canvas area.
Aspect-ratio conversion for existing videos
Reframe source footage into a new layout without rebuilding the video from scratch.
Prompt-guided canvas expansion
Use a text prompt to describe how the newly exposed area should be filled.
Multiple output ratios
Supports common landscape, portrait, square, and cinematic aspect ratios.
Flexible resolution options
Choose 540p, 720p, or 1080p depending on quality and budget needs.
Production-ready workflow
Useful for social repurposing, vertical edits, widescreen conversion, and creative reframing tasks.
| Parameter | Required | Description |
|---|---|---|
| video | Yes | Source video to reframe. The source video must be 30 seconds or less. |
| prompt | Yes | Text prompt describing the content to generate in the newly exposed canvas area. |
| size | No | Target aspect ratio: 16:9, 9:16, 1:1, 4:3, 3:4, or 21:9. Default: 16:9. |
| resolution | No | Output resolution: 540p, 720p, or 1080p. Default: 540p. |
540p for lower cost, 720p for balanced output, or 1080p for higher quality.Extend the sides with a realistic rainy city street, blurred traffic lights, and soft reflections that match the original nighttime mood.
Pricing is based on source video duration and output resolution.
| Resolution | Price per Started Second | 5s Example | 10s Example |
|---|---|---|---|
| 540p | $0.06 | $0.30 | $0.60 |
| 720p | $0.12 | $0.60 | $1.20 |
| 1080p | $0.36 | $1.80 | $3.60 |
size does not affect pricing9:16 clips for short-form platforms.21:9.540p or 720p when testing, then switch to 1080p for higher-end final delivery.video and prompt are required.Grab a WaveSpeedAI API key, then call POST https://api.wavespeed.ai/api/v3/luma/ray-3.2/video-reframing with your input as JSON. The endpoint returns a prediction id. Start polling the result endpoint around every 2 seconds, increase the interval for long-running tasks, and stop on any terminal status. On completed, read output values from data.outputs. Examples for Ray 3.2 Video Reframing below.
set -euo pipefail
: "${WAVESPEED_API_KEY:?Set WAVESPEED_API_KEY}"
REQUEST_BODY=$(cat <<'JSON'
{
"video": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
"prompt": "A cinematic shot of a city at sunset, soft golden light",
"size": "16:9",
"resolution": "540p"
}
JSON
)
# 1. Submit the prediction.
SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
-X POST "https://api.wavespeed.ai/api/v3/luma/ray-3.2/video-reframing" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $WAVESPEED_API_KEY" \
-d "$REQUEST_BODY")
TASK=$(printf '%s' "$SUBMIT_RESPONSE" | jq 'if has("data") then .data else . end')
PREDICTION_ID=$(printf '%s' "$TASK" | jq -r '.id')
if [ -z "$PREDICTION_ID" ] || [ "$PREDICTION_ID" = "null" ]; then
printf 'Submission response did not contain a prediction id
' >&2
exit 1
fi
RESULT_URL=$(printf '%s' "$TASK" | jq -r '.urls.get // empty')
if [ -z "$RESULT_URL" ]; then
RESULT_URL="https://api.wavespeed.ai/api/v3/predictions/$PREDICTION_ID/result"
fi
# 2. Poll until the prediction finishes.
while true; do
RESPONSE=$(curl --silent --show-error --fail-with-body "$RESULT_URL" \
-H "Authorization: Bearer $WAVESPEED_API_KEY")
RESULT=$(printf '%s' "$RESPONSE" | jq 'if has("data") then .data else . end')
STATUS=$(printf '%s' "$RESULT" | jq -r '.status')
case "$STATUS" in
completed) printf '%s\n' "$RESULT" | jq '.outputs'; break ;;
failed|cancelled|timeout) printf '%s\n' "$RESULT" | jq . >&2; exit 1 ;;
created|processing) sleep 2 ;;
*) printf 'Unexpected status: %s
' "$STATUS" >&2; exit 1 ;;
esac
doneconst submitUrl = "https://api.wavespeed.ai/api/v3/luma/ray-3.2/video-reframing";
const apiKey = process.env.WAVESPEED_API_KEY;
if (!apiKey) throw new Error('Set WAVESPEED_API_KEY');
async function requestJson(url, options = {}) {
const response = await fetch(url, options);
if (!response.ok) throw new Error(await response.text());
return response.json();
}
// 1. Submit the prediction.
const body = await requestJson(submitUrl, {
method: "POST",
headers: {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"video": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
"prompt": "A cinematic shot of a city at sunset, soft golden light",
"size": "16:9",
"resolution": "540p"
}),
});
const task = body.data ?? body;
if (!task.id) throw new Error("Submission response did not contain a prediction id");
const resultUrl = task.urls?.get ||
`https://api.wavespeed.ai/api/v3/predictions/${task.id}/result`;
// 2. Poll until the prediction finishes.
while (true) {
const resultBody = await requestJson(resultUrl, {
headers: { "Authorization": `Bearer ${apiKey}` },
});
const result = resultBody.data ?? resultBody;
if (result.status === "completed") {
console.log(result.outputs);
break;
}
if (["failed", "cancelled", "timeout"].includes(result.status)) throw new Error(JSON.stringify(result));
if (!["created", "processing"].includes(result.status)) throw new Error("Unexpected status: " + result.status);
await new Promise(resolve => setTimeout(resolve, 2000));
}import json
import os
import time
from urllib.request import Request, urlopen
api_key = os.environ["WAVESPEED_API_KEY"]
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
payload = {
"video": "https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4",
"prompt": "A cinematic shot of a city at sunset, soft golden light",
"size": "16:9",
"resolution": "540p"
}
def request_json(url, data=None):
request = Request(url, data=data, headers=headers, method="POST" if data else "GET")
with urlopen(request) as response:
return json.load(response)
# 1. Submit the prediction.
body = request_json("https://api.wavespeed.ai/api/v3/luma/ray-3.2/video-reframing", json.dumps(payload).encode())
task = body.get("data", body)
if not task.get("id"):
raise RuntimeError("Submission response did not contain a prediction id")
result_url = task.get("urls", {}).get("get") or f"https://api.wavespeed.ai/api/v3/predictions/{task['id']}/result"
# 2. Poll until the prediction finishes.
while True:
result_body = request_json(result_url)
result = result_body.get("data", result_body)
status = result.get("status")
if status == "completed":
print(result.get("outputs", []))
break
if status in {"failed", "cancelled", "timeout"}:
raise RuntimeError(result)
if status not in {"created", "processing"}:
raise RuntimeError(f"Unexpected status: {status}")
time.sleep(2)Ray 3.2 Video Reframing is a Luma model for video editing, exposed as a REST API on WaveSpeedAI. Luma Ray 3.2 Video Reframing is a fast AI video reframing model that changes an existing video’s aspect ratio and fills the newly exposed canvas from a prompt while preserving the source footage. Ready-to-use REST inference API for aspect ratio conversion, social media resizing, cinematic reframing, video outpainting, creator content, advertising creatives, and professional video editing workflows with simple integration, no coldstarts, and affordable pricing. You can call it programmatically or try it from the playground above.
POST your input parameters to the model's REST endpoint (shown in the API tab of this playground) with your WaveSpeedAI API key in the Authorization header. Submission returns a prediction ID. Poll the result endpoint starting around every 2 seconds, increase the interval for long-running tasks, and stop on any terminal status. The playground generates production-oriented Python, JavaScript, and cURL examples with timeouts, transient-error handling, and safe GET retries. Full request/response shape is documented at https://wavespeed.ai/docs/docs-api/luma/luma-ray-3.2-video-reframing.
Ray 3.2 Video Reframing starts at $0.060 per run. That figure is the base price — the final charge scales with the parameters you set in the form (output size, length, count, references, or whatever knobs this model exposes), so a higher-quality or larger output costs more than a minimal one. The exact cost for your current input is shown live next to the Generate button before you submit, and the actual per-call charge is recorded on the prediction afterwards.
Key inputs: `prompt`, `video`, `resolution`, `size`. The full JSON schema (types, defaults, allowed values) is rendered above the Generate button and mirrored in the API reference at https://wavespeed.ai/docs/docs-api/luma/luma-ray-3.2-video-reframing.
Median end-to-end generation time on WaveSpeedAI is around 69 seconds per request, based on recent successful runs. Queue time varies with global demand; live status is visible in the prediction record.
Commercial usage rights depend on the model's license, set by its provider (Luma). The license summary appears on the model card above; see WaveSpeedAI's Terms of Service for platform-level conditions.