Loading API documentation
Start Session
The client provides a convenient way to interact with the model API.
npm install @fal-ai/client@alpha @fal-ai/server-proxy@alphafal.realtime.open is currently available on the alpha release and may change in a minor version.
Keep FAL_KEY on your server and expose an authenticated proxy route to your browser. For a Next.js App Router application, create app/api/fal/proxy/route.ts:
import { route } from "@fal-ai/server-proxy/nextjs";
export const { GET, POST, PUT } = route;Set FAL_KEY in the server environment, and protect this route with your application's authentication before deploying it.
This deployment publishes a WMA WebRTC contract. The example uses fal.realtime.open; its media handlers, capture constraints, and control message are generated from the linked AsyncAPI document.
import { createFalClient } from "@fal-ai/client";
import { wma } from "@fal-ai/client/realtime";
const fal = createFalClient({ proxyUrl: "/api/fal/proxy" });
const session = fal.realtime.open(wma("minimax/h3-max/reference-director"), {
receive: [
"video",
"audio"
],
onMedia: (stream) => {
const element = document.querySelector("video");
if (element) element.srcObject = stream;
},
onData: (raw) => {
const message = JSON.parse(raw);
console.log(message);
},
onState: (state) => console.log("realtime:", state),
onError: (error) => console.error(error),
});
// Send any client message described below.
session.send({
"dialogue_words_per_second": 2,
"resolution": "768p",
"aspect_ratio": "16:9",
"reference_audio": [],
"reference_audio_urls": [],
"type": "configure",
"reference_image_urls": [],
"memory": 12,
"num_inference_steps": 10,
"prompt": "Photorealistic live-action cinema. Natural light and real materials, clear faces, grounded physical movement. Nora: adult woman, olive skin, long dark braid, burgundy bomber jacket, cream trousers; precise, competitive, generous. Milo: adult man, light skin, sandy-blond tight curls, small mustache, mustard sweater, dark jeans; distractible, athletic, optimistic. Keep the same faces, hair, outfits and body proportions throughout. Show each person separately and make their interaction readable. Nora and Milo jog along an open harbor promenade toward a small departing ferry. Milo carries a closed canvas bag. Nora points toward the gangway. A continuous adventurous short with occasional clear motivated cuts. Natural environmental sound, light music, no narration.",
"mxfp8_ref2va_attention": false,
"protocol_version": 1,
"prompt_version": 1,
"reference_images": [
{
"url": "https://v3b.fal.media/files/b/0aad61a3/c9LOOpJnQOyGHiFyqe2nL_epSrZDee.png",
"name": "Nora"
},
{
"url": "https://v3b.fal.media/files/b/0aad61a5/DlurMst_q9n1wsmoqwBYs_W2gpRpM6.png",
"name": "Milo"
}
],
"seed": 631011,
"pin_audio": false
});
// Later, release the peer connection and network resources:
// await session.close();The browser connects through your server proxy, which reads FAL_KEY from the server environment. Never put that key in browser code.
When running code on the client-side (e.g. in a browser, mobile app or GUI applications), make sure to not expose your FAL_KEY. Instead, use a server-side proxy to make requests to the API. For more information, check out our server-side integration guide.
Client contract for the WebRTC session created by the linked OpenAPI operation.
Tracks are described from the browser's perspective. Send tracks are captured by the browser and sent to the model; receive tracks come back from the model.
No send media tracks.
{
"frameRate": 24
}type: "configure"payload: objectAdditional properties: not allowed
promptstring* requiredAt least 1 character · At most 50000 characters
resolutionstringDefault: "480p"
Values: "480p", "544p", "640p", "704p", "768p", "1080p", "1440p"
aspect_ratiostringDefault: "16:9"
Values: "16:9", "9:16", "1:1"
reference_images(object & object)[]Default: []
maxItems: 9
object & objectMust match all of the following:
objectAdditional properties: not allowed
namestring | nullDefault: null
At most 64 characters when not null
urlstring* requiredAt least 1 character
fidelitystring | nullVision-conditioning detail for image references: high (768px), medium (512px) or low (256px). Omitted keeps the reference's previous fidelity, or high for a new reference. Ignored for audio references.
Default: null
When not null:
Values: "high", "medium", "low"
idstring | nullDefault: null
pattern: ^ref-[1-9][0-9]*$ when not null
objectAdditional properties: allowed
urlunknownreference_image_urlsstring[]Default: []
maxItems: 9
stringscriptobject[] | nullDefault: null
Must match at least one of the following:
object[]minItems: 1 · maxItems: 64
objectAdditional properties: not allowed
offsetnumber* requiredSeconds from the start of the first video generated under this script; fractions are allowed and quantize to the 24 fps frame grid. Text and audio placed here start at this moment. A beat carrying reference_images makes those identities available from the whole second at or before this offset, so its own prompt can show them immediately.
minimum: 0
promptstring | nullDefault: null
At least 1 character when not null · At most 50000 characters when not null
audio_urlstring | nullDefault: null
At least 1 character when not null
reference_images(object & object)[]Default: []
maxItems: 9
object & objectMust match all of the following:
objectAdditional properties: not allowed
namestring | nullDefault: null
At most 64 characters when not null
urlstring* requiredAt least 1 character
fidelitystring | nullVision-conditioning detail for image references: high (768px), medium (512px) or low (256px). Omitted keeps the reference's previous fidelity, or high for a new reference. Ignored for audio references.
Default: null
When not null:
Values: "high", "medium", "low"
idstring | nullDefault: null
pattern: ^ref-[1-9][0-9]*$ when not null
objectAdditional properties: allowed
urlunknownnullreference_audio(object & object)[]Default: []
maxItems: 3
object & objectMust match all of the following:
objectAdditional properties: not allowed
namestring | nullDefault: null
At most 64 characters when not null
urlstring* requiredAt least 1 character
fidelitystring | nullVision-conditioning detail for image references: high (768px), medium (512px) or low (256px). Omitted keeps the reference's previous fidelity, or high for a new reference. Ignored for audio references.
Default: null
When not null:
Values: "high", "medium", "low"
idstring | nullDefault: null
pattern: ^ref-[1-9][0-9]*$ when not null
objectAdditional properties: allowed
urlunknownreference_audio_urlsstring[]Default: []
maxItems: 3
stringpin_audiobooleanDefault: false
memoryintegerNumber of prior segment prompts retained as context for future prompt expansion.
Default: 12
minimum: 1 · maximum: 50
audio_bitrateinteger | nullSession audio target in bits/s: 96000, 128000, or 192000. Explicit values use Opus audio mode on direct WebRTC; LiveKit uses its native mode with the same bitrate target. Null preserves transport defaults (WebRTC: 96000, voip). Immutable; reconnect to compare.
Default: null
When not null:
Values: 96000, 128000, 192000
seedinteger | nullDefault: null
num_inference_stepsintegerDefault: 10
minimum: 1 · maximum: 50
mxfp8_ref2va_attentionbooleanUse MXFP8 attention for dense generation steps.
Default: false
forced_cut_max_segmentsinteger | nullMost segments in one unbroken continuation run before a forced hard cut opens a fresh shot (Ref2VA burn-in mitigation). 0 disables forced cuts; omitted keeps the deployment default. Pinned for the whole session.
Default: null
minimum: 0 when not null · maximum: 64 when not null
dialogue_words_per_secondnumberSpoken words per second of new screen time the planner budgets dialogue against. The default keeps delivery calm; raise it for deliberately fast talkers, lower it for sparser dialogue.
Default: 2
minimum: 0.5 · maximum: 6
typestring* requiredConstant: "configure"
protocol_versionintegerConstant: 1
prompt_versioninteger* requiredminimum: 1
Nora and Milo jog along an open harbor promenade toward a small departing ferry. Milo carries a closed canvas bag. Nora points toward the gangway.
{
"dialogue_words_per_second": 2,
"resolution": "768p",
"aspect_ratio": "16:9",
"reference_audio": [],
"reference_audio_urls": [],
"type": "configure",
"reference_image_urls": [],
"memory": 12,
"num_inference_steps": 10,
"prompt": "Photorealistic live-action cinema. Natural light and real materials, clear faces, grounded physical movement. Nora: adult woman, olive skin, long dark braid, burgundy bomber jacket, cream trousers; precise, competitive, generous. Milo: adult man, light skin, sandy-blond tight curls, small mustache, mustard sweater, dark jeans; distractible, athletic, optimistic. Keep the same faces, hair, outfits and body proportions throughout. Show each person separately and make their interaction readable. Nora and Milo jog along an open harbor promenade toward a small departing ferry. Milo carries a closed canvas bag. Nora points toward the gangway. A continuous adventurous short with occasional clear motivated cuts. Natural environmental sound, light music, no narration.",
"mxfp8_ref2va_attention": false,
"protocol_version": 1,
"prompt_version": 1,
"reference_images": [
{
"url": "https://v3b.fal.media/files/b/0aad61a3/c9LOOpJnQOyGHiFyqe2nL_epSrZDee.png",
"name": "Nora"
},
{
"url": "https://v3b.fal.media/files/b/0aad61a5/DlurMst_q9n1wsmoqwBYs_W2gpRpM6.png",
"name": "Milo"
}
],
"seed": 631011,
"pin_audio": false
}type: "ping"payload: objectAdditional properties: not allowed
typestring* requiredConstant: "ping"
tsnumber* required{
"type": "ping",
"ts": 0
}type: "prompt"payload: objectAdditional properties: not allowed
promptstring | nullDefault: null
At least 1 character when not null · At most 50000 characters when not null
reference_images(object & object)[] | nullDefault: null
Must match at least one of the following:
(object & object)[]maxItems: 9
object & objectMust match all of the following:
objectAdditional properties: not allowed
namestring | nullDefault: null
At most 64 characters when not null
urlstring* requiredAt least 1 character
fidelitystring | nullVision-conditioning detail for image references: high (768px), medium (512px) or low (256px). Omitted keeps the reference's previous fidelity, or high for a new reference. Ignored for audio references.
Default: null
When not null:
Values: "high", "medium", "low"
idstring | nullDefault: null
pattern: ^ref-[1-9][0-9]*$ when not null
objectAdditional properties: allowed
urlunknownnullreference_image_urlsstring[] | nullDefault: null
Must match at least one of the following:
string[]maxItems: 9
stringnullscriptobject[] | nullDefault: null
Must match at least one of the following:
object[]minItems: 1 · maxItems: 64
objectAdditional properties: not allowed
offsetnumber* requiredSeconds from the start of the first video generated under this script; fractions are allowed and quantize to the 24 fps frame grid. Text and audio placed here start at this moment. A beat carrying reference_images makes those identities available from the whole second at or before this offset, so its own prompt can show them immediately.
minimum: 0
promptstring | nullDefault: null
At least 1 character when not null · At most 50000 characters when not null
audio_urlstring | nullDefault: null
At least 1 character when not null
reference_images(object & object)[]Default: []
maxItems: 9
object & objectMust match all of the following:
objectAdditional properties: not allowed
namestring | nullDefault: null
At most 64 characters when not null
urlstring* requiredAt least 1 character
fidelitystring | nullVision-conditioning detail for image references: high (768px), medium (512px) or low (256px). Omitted keeps the reference's previous fidelity, or high for a new reference. Ignored for audio references.
Default: null
When not null:
Values: "high", "medium", "low"
idstring | nullDefault: null
pattern: ^ref-[1-9][0-9]*$ when not null
objectAdditional properties: allowed
urlunknownnullaudio_behaviorstring'replace' cuts to this audio at the next chunk; 'queue' appends it.
Default: "replace"
Values: "replace", "queue"
replanbooleanWhen a prompt is included: true (default) busts the planned prompt queue so the new direction applies at the next undispatched chunk; false appends the direction after the already-planned chunks.
Default: true
reference_audio(object & object)[] | nullDefault: null
Must match at least one of the following:
(object & object)[]maxItems: 3
object & objectMust match all of the following:
objectAdditional properties: not allowed
namestring | nullDefault: null
At most 64 characters when not null
urlstring* requiredAt least 1 character
fidelitystring | nullVision-conditioning detail for image references: high (768px), medium (512px) or low (256px). Omitted keeps the reference's previous fidelity, or high for a new reference. Ignored for audio references.
Default: null
When not null:
Values: "high", "medium", "low"
idstring | nullDefault: null
pattern: ^ref-[1-9][0-9]*$ when not null
objectAdditional properties: allowed
urlunknownnullreference_audio_urlsstring[] | nullDefault: null
Must match at least one of the following:
string[]maxItems: 3
stringnulltypestring* requiredConstant: "prompt"
prompt_versioninteger* requiredminimum: 1
script_modestring'replace' cuts to the script at the next chunk; 'append' queues it.
Default: "replace"
Values: "replace", "append"
{
"type": "prompt",
"prompt_version": 1
}type: "stop"payload: objectAdditional properties: not allowed
typestring* requiredConstant: "stop"
{
"type": "stop"
}type: "audio_applied"payload: objectAn audio update was accepted; it conditions the next eligible chunk.
starts_at_chunk_index is the first chunk that can carry it (the next
undispatched chunk for replace; for queue the chunk where the
preceding sources end, if already known).
transcribedboolean* requiredduration_secondsnumber* requiredexclusiveMinimum: 0
prompt_versioninteger* requiredminimum: 1
sourcestring* requiredremaining_secondsnumber* requiredminimum: 0
typestring* requiredConstant: "audio_applied"
queued_sourcesinteger* requiredminimum: 0
behaviorstring* requiredValues: "replace", "queue"
{
"transcribed": true,
"duration_seconds": 5e-324,
"prompt_version": 1,
"source": "string",
"remaining_seconds": 0,
"type": "audio_applied",
"queued_sources": 0,
"behavior": "replace"
}type: "audio_exhausted"payload: objectAccepted audio ran out inside this chunk; the rest is silence.
Later chunks continue without audio conditioning (checkpoint continuation on the same family) until new audio is accepted.
typestring* requiredConstant: "audio_exhausted"
chunk_indexinteger* requiredminimum: 0
silent_secondsnumber* requiredminimum: 0
source_versioninteger | nullDefault: null
minimum: 0 when not null
{
"type": "audio_exhausted",
"chunk_index": 0,
"silent_seconds": 0
}type: "audio_pending"payload: objecttypestring* requiredConstant: "audio_pending"
prompt_versioninteger* requiredminimum: 1
behaviorstring* requiredValues: "replace", "queue"
{
"type": "audio_pending",
"prompt_version": 1,
"behavior": "replace"
}type: "audio_rejected"payload: objectreasonstring* requiredValues: "invalid_audio", "content_policy", "preparation_failed", "queue_full", "stale_prompt_version"
typestring* requiredConstant: "audio_rejected"
errorstring* requiredprompt_versioninteger* requiredminimum: 1
{
"reason": "invalid_audio",
"type": "audio_rejected",
"error": "string",
"prompt_version": 1
}type: "chunk"payload: objectroutestring* requiredConstant: "k10-reference"
next_generation_estimate_secondsnumber* requiredminimum: 0
native_playable_frame_countinteger | nullDefault: null
exclusiveMinimum: 0 when not null
trimmed_context_framesinteger* requiredminimum: 0
buffer_depth_secondsnumber* requiredminimum: 0
buffer_depth_chunksinteger* requiredminimum: 0
dispatchobject* requiredoverhead_msnumber* requiredminimum: 0
wall_msnumber* requiredminimum: 0
classified_msnumber* requiredminimum: 0
phases_msobject* requiredAdditional properties: number
numbertypestring* requiredConstant: "chunk"
script_versioninteger | nullDefault: null
minimum: 1 when not null
scheduling_lead_msnumber* requiredrequested_duration_secondsinteger* requiredminimum: 5 · maximum: 15
script_offset_secondsinteger | nullDefault: null
minimum: 0 when not null
script_end_keyframeboolean | nullDefault: null
generated_frame_countinteger* requiredexclusiveMinimum: 0
prompt_versioninteger* requiredminimum: 1
scheduling_slack_msnumber* requiredgeneration_secondsnumber* requiredminimum: 0
hard_cutbooleanDefault: false
presented_frame_countinteger | nullDefault: null
exclusiveMinimum: 0 when not null
chunk_indexinteger* requiredminimum: 0
playback_secondsnumber* requiredexclusiveMinimum: 0
{
"route": "k10-reference",
"next_generation_estimate_seconds": 0,
"trimmed_context_frames": 0,
"buffer_depth_seconds": 0,
"buffer_depth_chunks": 0,
"dispatch": {
"overhead_ms": 0,
"wall_ms": 0,
"classified_ms": 0,
"phases_ms": {}
},
"type": "chunk",
"scheduling_lead_ms": 0,
"requested_duration_seconds": 5,
"generated_frame_count": 1,
"prompt_version": 1,
"scheduling_slack_ms": 0,
"generation_seconds": 0,
"chunk_index": 0,
"playback_seconds": 5e-324
}type: "chunk_metrics"payload: objectunitsstring* requiredConstant: "ms"
routestring* requiredConstant: "k10-reference"
chunk_indexinteger* requiredminimum: 0
phases_msobject* requiredAdditional properties: number
numbergaugesobject* requiredAdditional properties: number
numbertypestring* requiredConstant: "chunk_metrics"
chunk_consumable_interval_msnumber | nullDefault: null
minimum: 0 when not null
chunk_consumable_ready_msnumber | nullDefault: null
minimum: 0 when not null
{
"units": "ms",
"route": "k10-reference",
"chunk_index": 0,
"phases_ms": {},
"gauges": {},
"type": "chunk_metrics"
}type: "configured"payload: objectchunk_durationinteger | nullDefault: null
minimum: 5 when not null · maximum: 15 when not null
prompt_versioninteger* requiredminimum: 1
resolutionstring | nullDefault: null
When not null:
Values: "480p", "544p", "640p", "704p", "768p", "1080p", "1440p"
enable_safety_checkerboolean* requiredaccelerationstring | nullDefault: null
When not null:
Values: "none", "regular"
has_initial_imageboolean | nullDefault: null
aspect_ratiostring | nullDefault: null
When not null:
Values: "16:9", "9:16", "1:1"
has_initial_audioboolean | nullDefault: null
typestring* requiredConstant: "configured"
audio_bitrateinteger | nullDefault: null
When not null:
Values: 96000, 128000, 192000
memoryinteger | nullDefault: null
minimum: 1 when not null · maximum: 50 when not null
{
"prompt_version": 1,
"enable_safety_checker": true,
"type": "configured"
}type: "deadline_missed"payload: objectlate_by_secondsnumber* requiredminimum: 0
typestring* requiredConstant: "deadline_missed"
chunk_indexinteger* requiredminimum: 0
behaviorstring* requiredConstant: "freeze_video_and_silence_audio_until_ready"
{
"late_by_seconds": 0,
"type": "deadline_missed",
"chunk_index": 0,
"behavior": "freeze_video_and_silence_audio_until_ready"
}type: "error"payload: objectcodestring* requiredValues: "balance_unavailable", "content_policy", "configuration_timeout", "generation_failed", "generation_timeout", "immutable_settings", "initialization_timeout", "invalid_initial_image", "invalid_initial_audio", "invalid_initial_script", "invalid_input", "invalid_message", "not_configured", "stale_prompt_version"
typestring* requiredConstant: "error"
errorstring* requireddetailobject[] | nullDefault: null
Must match at least one of the following:
object[]objectnullprompt_versioninteger | nullDefault: null
minimum: 1 when not null
{
"code": "balance_unavailable",
"type": "error",
"error": "string"
}type: "pong"payload: objectclient_tsnumber* requiredtypestring* requiredConstant: "pong"
{
"client_ts": 0,
"type": "pong"
}type: "prompt_applied"payload: objectA direction (or script) is admitted; the script fields report scripts.
script_origin_chunk_index is the first chunk generated under the
script when that is already fixed (a replacement binds to the next
undispatched chunk); an appended script reports None until it starts.
script_beatsinteger | nullDefault: null
minimum: 1 when not null
script_queuedinteger | nullDefault: null
minimum: 0 when not null
typestring* requiredConstant: "prompt_applied"
script_modestring | nullDefault: null
When not null:
Values: "replace", "append"
script_origin_chunk_indexinteger | nullDefault: null
minimum: 0 when not null
prompt_versioninteger* requiredminimum: 1
{
"type": "prompt_applied",
"prompt_version": 1
}type: "prompt_pending"payload: objecttypestring* requiredConstant: "prompt_pending"
prompt_versioninteger* requiredminimum: 1
{
"type": "prompt_pending",
"prompt_version": 1
}type: "prompt_rejected"payload: objectreasonstring* requiredValues: "content_policy", "preparation_failed", "stale_prompt_version", "invalid_script", "infeasible_timing", "invalid_audio", "invalid_image", "queue_full"
typestring* requiredConstant: "prompt_rejected"
errorstring | nullDefault: null
prompt_versioninteger* requiredminimum: 1
{
"reason": "content_policy",
"type": "prompt_rejected",
"prompt_version": 1
}type: "reference_state"payload: objecttypestring* requiredConstant: "reference_state"
prompt_versioninteger* requiredreferencesobject[]* requiredobjectrevisioninteger* requiredkindstring* requiredValues: "image", "audio"
idstring* requirednamestring | nullDefault: null
{
"type": "reference_state",
"prompt_version": 0,
"references": []
}type: "session_info"payload: objectbillable_units_per_playable_secondobjectDefault: {"1080p":1.2,"544p":1.04,"704p":1.15,"768p":1.2,"640p":1.1,"480p":1,"1440p":1.2}
Additional properties: number
numberpricing_statusstringDefault: "provisional-experiment"
session_limit_scopestringDefault: "configured"
min_num_inference_stepsintegerDefault: 1
dialogue_words_per_secondnumberDefault: 2
appstringConstant: "minimax-h3-max-reference-director"
max_num_inference_stepsintegerDefault: 50
scriptsbooleanDefault: true
typestring* requiredConstant: "session_info"
min_chunk_durationintegerDefault: 5
backend_selectionstringDefault: "resident-k10-reference"
default_resolutionstringDefault: "480p"
Values: "480p", "544p", "640p", "704p", "768p", "1080p", "1440p"
prompt_deck_sizeintegerDefault: 6
accelerationsstring[]Default: ["none"]
stringforced_cut_max_segmentsintegerresolutionsstring[]Default: ["480p","544p","640p","704p","768p","1080p","1440p"]
stringValues: "480p", "544p", "640p", "704p", "768p", "1080p", "1440p"
reference_audio_modestringDefault: "sequential-content-windows"
continuation_context_framesintegerDefault: 39
protocol_versionintegerConstant: 1
controller_machine_typestringDefault: "GPU-B300/GPU-B200 (8 GPUs)"
max_session_secondsnumber | nullDefault: null
fpsintegerDefault: 24
default_num_inference_stepsintegerDefault: 10
default_chunk_durationintegerDefault: 10
max_chunk_durationintegerDefault: 15
one_session_per_machinebooleanDefault: true
default_pin_audiobooleanDefault: false
{
"app": "minimax-h3-max-reference-director",
"type": "session_info",
"protocol_version": 1
}type: "session_metrics"payload: objectunitsstring* requiredConstant: "ms"
history_sizeinteger* requiredminimum: 0
finalbooleanDefault: false
gaugesobject* requiredAdditional properties: number
numberphasesobject* requiredAdditional properties: object
objecttotal_msnumber* requiredminimum: 0
max_msnumber* requiredminimum: 0
countinteger* requiredminimum: 0
p50_msnumber* requiredminimum: 0
p95_msnumber* requiredminimum: 0
typestring* requiredConstant: "session_metrics"
session_wall_msnumber* requiredminimum: 0
history_limitinteger* requiredminimum: 1
{
"units": "ms",
"history_size": 0,
"gauges": {},
"phases": {},
"type": "session_metrics",
"session_wall_ms": 0,
"history_limit": 1
}type: "stream_exhausted"payload: objectreasonstring* requiredValues: "stopped", "session_limit"
typestring* requiredConstant: "stream_exhausted"
chunksinteger* requiredminimum: 0
{
"reason": "stopped",
"type": "stream_exhausted",
"chunks": 0
}