Seamless 5-second sequence connecting the three key poses: the skater crouches and pops the board, rises into a level ollie, then lands and rolls away. Camera: low tracking shot at board height, steady lateral move. Lighting: late afternoon plaza sun. Native audio: board pop, wheels on concrete, a soft landing. No logos, no readable text, no products, no packaging, no prices, no CTA, no advertising, no watermark, no brand marks.
FLUX 3 Keyframes to Video API
blackforestlabs/flux-3/keyframes-to-videoFLUX 3 Keyframes to Video places up to 10 keyframes along a 24 fps timeline to direct 5–20 seconds of continuous video with optional synchronized native audio. Choreograph complex shot sequences, character staging, and camera transitions across precise temporal anchors.
Add at least one keyframe image.
Your generated video will appear here
Add your prompt and required media, review the settings, then click Run.
Examples
REST API
Quick Start
Authenticate with the API, supply timeline-indexed keyframes, and retrieve video using the task ID.
Connect to the Vidgo API
Create an API key, store securely on your server, and include Authorization: Bearer VIDGO_API_KEY.
- Endpoint
- POST
https://api.vidgo.ai/api/generate/submit - Authentication
- Authorization: Bearer VIDGO_API_KEY
Submit one generation task
Fill parameters with 24 fps keyframe objects, submit, and save task_id for progress queries.
REQUEST_BODY=$(cat <<'JSON'
{
"model": "blackforestlabs/flux-3/keyframes-to-video",
"input": {
"prompt": "Seamless 5-second sequence connecting the three key poses: the skater crouches and pops the board, rises into a level ollie, then lands and rolls away. Camera: low tracking shot at board height, steady lateral move. Lighting: late afternoon plaza sun. Native audio: board pop, wheels on concrete, a soft landing. No logos, no readable text, no products, no packaging, no prices, no CTA, no advertising, no watermark, no brand marks.",
"duration": 5,
"resolution": "720p",
"aspect_ratio": "auto",
"sound": true,
"keyframes": [
{
"frame_index": 0,
"image_url": "https://cdn.vidgo.ai/apis/models/blackforestlabs/flux-3/keyframes-to-video/v1/01/input-keyframe-0.webp"
},
{
"frame_index": 60,
"image_url": "https://cdn.vidgo.ai/apis/models/blackforestlabs/flux-3/keyframes-to-video/v1/01/input-keyframe-60.webp"
},
{
"frame_index": 120,
"image_url": "https://cdn.vidgo.ai/apis/models/blackforestlabs/flux-3/keyframes-to-video/v1/01/input-keyframe-120.webp"
}
]
}
}
JSON
)
RESPONSE=$(curl --silent --show-error --fail-with-body \
--request POST \
--url "https://api.vidgo.ai/api/generate/submit" \
--header "Authorization: Bearer $VIDGO_API_KEY" \
--header "Content-Type: application/json" \
--data "$REQUEST_BODY")
CODE=$(printf '%s' "$RESPONSE" | jq -r '.code // empty')
if [ "$CODE" != "0" ] && [ "$CODE" != "200" ]; then
printf 'API error: %s
' "$RESPONSE" >&2
exit 1
fi
printf '%s
' "$RESPONSE"Wait for the result
Poll with task_id while running, stop on finished or failed. On success, download data.files[].file_url.
Track status
GET https://api.vidgo.ai/api/generate/status/{task_id}Poll status with a 2-second base interval. Continue querying while not_started or running, and stop on finished or failed. You can also supply callback_url in the request to receive webhook notifications.
not_startedrunningfinishedfailed{
"code": 200,
"data": {
"task_id": "task-flux3-k2v-...",
"status": "running",
"created_time": "2026-09-16T10:00:00Z"
}
}{
"code": 200,
"data": {
"task_id": "task-unified-...",
"status": "finished",
"files": [
{
"file_url": "https://storage.vidgo.ai/generated/video.mp4",
"file_type": "video"
}
],
"created_time": "2026-08-22T10:00:00Z",
"progress": 100,
"error_message": null
}
}Complete runnable example
Expand for an end-to-end integration script with response checks, polling loops, and error boundaries.
set -euo pipefail
: "${VIDGO_API_KEY:?Set VIDGO_API_KEY in your environment}"
REQUEST_BODY=$(cat <<'JSON'
{
"model": "blackforestlabs/flux-3/keyframes-to-video",
"input": {
"prompt": "Seamless 5-second sequence connecting the three key poses: the skater crouches and pops the board, rises into a level ollie, then lands and rolls away. Camera: low tracking shot at board height, steady lateral move. Lighting: late afternoon plaza sun. Native audio: board pop, wheels on concrete, a soft landing. No logos, no readable text, no products, no packaging, no prices, no CTA, no advertising, no watermark, no brand marks.",
"duration": 5,
"resolution": "720p",
"aspect_ratio": "auto",
"sound": true,
"keyframes": [
{
"frame_index": 0,
"image_url": "https://cdn.vidgo.ai/apis/models/blackforestlabs/flux-3/keyframes-to-video/v1/01/input-keyframe-0.webp"
},
{
"frame_index": 60,
"image_url": "https://cdn.vidgo.ai/apis/models/blackforestlabs/flux-3/keyframes-to-video/v1/01/input-keyframe-60.webp"
},
{
"frame_index": 120,
"image_url": "https://cdn.vidgo.ai/apis/models/blackforestlabs/flux-3/keyframes-to-video/v1/01/input-keyframe-120.webp"
}
]
}
}
JSON
)
SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
--request POST \
--url "https://api.vidgo.ai/api/generate/submit" \
--header "Authorization: Bearer $VIDGO_API_KEY" \
--header "Content-Type: application/json" \
--data "$REQUEST_BODY")
TASK_ID=$(printf '%s' "$SUBMIT_RESPONSE" | jq -r '.data.task_id // .task_id // empty')
BUSINESS_CODE=$(printf '%s' "$SUBMIT_RESPONSE" | jq -r '.code // empty')
if [ "$BUSINESS_CODE" != "0" ] && [ "$BUSINESS_CODE" != "200" ]; then
printf 'Submit failed:
%s
' "$SUBMIT_RESPONSE" >&2
exit 1
fi
if [ -z "$TASK_ID" ]; then
printf 'Submit response did not include task_id:
%s
' "$SUBMIT_RESPONSE" >&2
exit 1
fi
START_TIME=$(date +%s)
POLL_DELAY=2
while true; do
if [ $(( $(date +%s) - START_TIME )) -ge 600 ]; then
printf 'Timed out after 600 seconds
' >&2
exit 1
fi
STATUS_RESPONSE=$(curl --silent --show-error --fail-with-body \
--url "https://api.vidgo.ai/api/generate/status/$TASK_ID" \
--header "Authorization: Bearer $VIDGO_API_KEY")
STATUS=$(printf '%s' "$STATUS_RESPONSE" | jq -r '.data.status // .status // empty')
BUSINESS_CODE=$(printf '%s' "$STATUS_RESPONSE" | jq -r '.code // empty')
if [ "$BUSINESS_CODE" != "0" ] && [ "$BUSINESS_CODE" != "200" ]; then
printf 'Status request failed:
%s
' "$STATUS_RESPONSE" >&2
exit 1
fi
case "$STATUS" in
finished)
printf '%s' "$STATUS_RESPONSE" | jq -r '(.data.files // .files // [])[]?.file_url'
break
;;
failed)
printf '%s' "$STATUS_RESPONSE" | jq -r '.data.error_message // .error_message // "Generation failed"' >&2
exit 1
;;
not_started|running)
sleep "$POLL_DELAY"
if [ "$POLL_DELAY" -lt 10 ]; then POLL_DELAY=$((POLL_DELAY + 1)); fi
;;
*)
printf 'Unexpected task status: %s
' "$STATUS" >&2
exit 1
;;
esac
doneInput parameters
The table lists available input parameters, types, and defaults. Request examples also include the required top-level model field. Prepare inputs and configure output specifications.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| prompt | string | Yes | — | Describes transition motion, camera movement, and audio between keyframes. |
| keyframes | object[] | Yes | — | 1–10 keyframe objects, each with a public image URL and a unique integer frame_index from 0 through duration × 24 inclusive. |
| keyframes[].frame_index | integer | Yes | — | Integer frame position along the 24 fps timeline (0–480). |
| keyframes[].image_url | string | Yes | — | Public URL for this specific keyframe image. |
| duration | integer | No | 5 | Output video duration in seconds from 5 to 20. |
| resolution | string | No | 720p | Output resolution, 720p or 1080p. |
| aspect_ratio | string | No | auto | Framing ratio: auto, 21:9, 2:1, 16:9, 4:3, 1:1, 3:4, or 9:16. |
| sound | boolean | No | true | Whether to generate native synchronized audio. |
Response Fields
A successful submission returns a task ID. Status queries provide progress, output files, and error details when a task fails.
| Field | Type | Description |
|---|---|---|
| code | integer | Application result code; successful responses use 0 or 200. |
| message | string | Human-readable message or error detail when present. |
| data.task_id | string | Task identifier used for querying generation status. |
| data.status | string | not_started, running, finished, or failed. |
| data.created_time | string | Task creation timestamp in date-time format. |
| data.progress | integer | Progress percentage reported from 0 to 100. |
| data.files[] | array | Array of output files generated upon task completion. |
| data.files[].file_url | string | Public URL for the generated video file. |
| data.files[].file_type | string | Output file MIME category, such as video. |
| data.error_message | string | null | Failure details when status is failed. |
Task Lifecycle
Continue querying while status is not_started or running. End polling at finished or failed, then process output files or error details respectively.
not_startedThe task was accepted and is waiting in the queue.
runningGeneration is in progress. Continue polling the task_id.
finishedGeneration succeeded. Read video URLs from data.files[].file_url.
failedGeneration failed. Read data.error_message and halt polling.
Polling and Errors
- AuthenticationOn 401 response, verify the Bearer API key in the Authorization header and retry.
- ValidationOn 400, check that there are 1–10 keyframes with unique integer indices from 0 through duration × 24.
- Network and timeoutIf status polling encounters network interruptions, retain task_id and retry status queries.
- Polling intervalPoll status with a 2-second base interval, extending intervals for longer renders.
- Terminal statesContinue polling only on not_started or running. Stop immediately once finished or failed.
- Callback optionProvide callback_url in request top level to receive final task payloads via webhook.
Endpoint limits
| Specification | Value | Details |
|---|---|---|
| Input mode | 1–10 Keyframes + Prompt | Time-indexed frames on 24 fps base with motion prompt. |
| Output | Video with native audio | Returns asynchronous task ID yielding standard MP4 video. |
| Duration | 5–20 seconds | Integer range, default 5 seconds. |
| Resolution | 720p / 1080p | Default is 720p. |
| Aspect ratio | 8 options (including auto) | auto, 21:9, 2:1, 16:9, 4:3, 1:1, 3:4, 9:16, default auto. |
| Billing basis | Duration × Resolution rate | 34 credits/sec for 720p, 58 credits/sec for 1080p. |
FLUX 3 Keyframes to Video
FLUX 3 Keyframes to Video gives creators temporal directing control for multi-shot blocking and complex visual effects. Position up to 10 keyframes along a 24 fps timeline to establish critical story moments, and let the model synthesize physical dynamics, camera movement, and native audio connecting each frame.
Why Choose This?
24 fps timeline precisionPin keyframes to exact frame indices (0–480) on a 24 fps timebase, precisely commanding when visual beats occur in the edit.
Choreograph up to 10 keyframesPosition 1 to 10 still frames in a single task, enabling complex multi-beat sequences and diverse viewpoint changes.
Positioned KeyframesPosition each image with frame_index and use the prompt to direct subject motion and camera changes.
Prompt-coordinated directionUse prompt text to choreograph intermediate actions and camera pans between keyframes, turning stills into dynamic storytelling.
Timeline-synchronized native soundGenerates audio that shifts alongside keyframe progression, matching room tones, foley, and music to evolving scene geometry.
Production-ready 720p and 1080pDelivers sharp 720p and 1080p renders that maintain edge integrity and textural depth across complex motion sequences.
Parameters
| Parameter | Requirement | Description |
|---|---|---|
| prompt | Required | String. Directs motion transitions, camera movements, and native audio cues connecting each temporal keyframe. |
| keyframes | Required | 1–10 keyframe objects, each with a public image URL and a unique integer frame_index from 0 through duration × 24 inclusive. |
| duration | Optional | Integer. Sets output video duration in seconds from 5 to 20; the Playground preselects 5 seconds. Default 5 |
| resolution | Optional | String. Sets output resolution to 720p or 1080p; the Playground preselects 720p. Default 720p1080p |
| aspect_ratio | Optional | String. Controls framing ratio, supporting auto and standard formats; the Playground preselects auto. Default auto21:92:116:94:31:13:49:16 |
| sound | Optional | Boolean. Controls whether native synchronized audio is generated alongside video; default is true. Default truefalse |
How to Use
Plan timeline and keyframesCalculate frame indices at 24 fps and prepare 1–10 public image URLs. Keep indices unique and within 0 through duration × 24.
Direct motion and transitionsIn prompt, describe how the subject advances across successive keyframes, detailing camera movement and audio cues.
Set total durationSpecify an integer duration between 5 and 20 seconds, verifying all frame_index values fall within duration × 24.
Choose resolution and aspect ratioPick 720p or 1080p resolution and set an appropriate aspect ratio or leave set to auto.
Configure sound settingKeep sound set to true to synthesize matching audio cues across the timeline, or set to false for silent video.
Generate and review sequenceConfirm the estimated credits, click Run, and inspect the continuous motion linking your keyframes before downloading.
Pricing
Billed per output second by resolution tier, including native synchronized audio. 1 credit = $0.005.
| Usage | Rate | Details |
|---|---|---|
| 720p | 34 credits / sec ($0.17 / sec) | Default 5s at 720p is 170 credits ($0.85). |
| 1080p | 58 credits / sec ($0.29 / sec) | 5s at 1080p is 290 credits ($1.45). |
Best Use Cases
Storyboard directing and blockingMap consecutive storyboard panels onto an explicit timeline, turning concept art into continuous cinematic footage.
Complex character choreographyPin key performance postures at exact seconds, generating natural dance, acrobatics, or sports sequences.
Multi-angle product showcaseAnchor front, profile, and macro shots at designated beats to produce a seamless 360-degree commercial reel.
Time-lapse environmental shiftsPlace dawn, midday, and twilight stills along the timeline to create atmospheric day-to-night transitions.
Pro Tips
- Remember the 24 fps formula: 1s = 24 frames, 2.5s = 60 frames, 5s = 120 frames, with maximum index equal to duration × 24.
- Choose keyframe positions for the intended shot, keeping every frame_index unique and within the output timeline.
- Keep intervals between adjacent keyframes at 12 frames (0.5s) or more to give the physical engine room to interpolate naturally.
- Sequence prompt directions to match timeline beats, e.g., 'dolly right for first 2 seconds, then push into close-up'.
- Coordinate sound design with critical visual beats, such as 'heavy door latch clicks shut exactly at the close-up'.
Notes
- 1–10 keyframe objects, each with a public image URL and a unique integer frame_index from 0 through duration × 24 inclusive.
- Every frame_index must fall within the range 0 to duration × 24 and must be distinct.
- After submission via API, record the returned task_id to poll progress and download the completed asset.
- Rendered videos are output in standard MP4 format and can be dropped directly into timelines to link neighboring shots.
Related Endpoints
FLUX 3 Keyframes to Video API frequently asked questions
What is the FLUX 3 Keyframes to Video API?
FLUX 3 Keyframes to Video is a Black Forest Labs model for interpolating continuous video across multiple chronological keyframes positioned along a timeline. It empowers creators to place up to 10 still frames onto a 24 fps timebase, generating 5 to 20 seconds of cinematic footage up to 1080p resolution with optional synchronized native audio. Rooted in multi-anchor spatiotemporal interpolation, it seamlessly unites shot transitions, character staging, and lighting changes for director-level storyboard execution. You can call it programmatically or try it from the playground above.
How is the 24 fps timeline frame index calculated for keyframes?
The timeline runs on a fixed 24 fps base. The integer frame_index is calculated as seconds × 24 (e.g., 0s = 0, 1s = 24, 2.5s = 60, 5s = 120, 20s = 480). All specified frame_index values must fall within the range 0 to duration × 24.
Does the first keyframe index have to be 0?
No. Every keyframe follows the same rule: frame_index must be an integer from 0 through duration × 24 and must not repeat another keyframe index.
How many keyframes are supported and what is the ideal spacing?
The keyframes array accepts 1 to 10 objects. To ensure fluid physics transitions, maintaining a spacing of at least 12 frames (0.5 seconds) between adjacent keyframes is recommended.
How should prompts be written to coordinate multiple keyframes?
Describe the narrative flow chronologically across the sequence. For example, 'smooth tracking from initial stance toward the second beat, then tilting up toward the final posture' guides the interpolation engine through successive anchors.
How is synchronized native audio synthesized across keyframes?
When sound is set to true, the model evaluates visual progressions across all keyframes alongside prompt audio cues to synthesize matching dynamic sound effects and ambient room tones aligned with each temporal point.
Which endpoint is recommended if I only need start and end anchors?
If your shot requires only an opening still and a closing still, the FLUX 3 First Last Frame to Video endpoint is recommended, as it accepts a simple 2-item array without requiring 24 fps frame index calculations.



