# H3 Max Director

> Direct continuous, realtime video streams with live prompts while preserving characters, settings, and story continuity.


## Overview

- **Endpoint**: `https://fal.run/minimax/h3-max/director`
- **Model ID**: `minimax/h3-max/director`
- **Category**: text-to-video
- **Kind**: inference
**Description**: H3 Max Director generates continuous real-time video that can be directed while it streams. Send new prompts during a session to evolve the action while maintaining visual, character, and scene continuity.



## Pricing

Sessions cost $0.02 per second of video generated. 

The promotional price expires on Sep 14th, with list price being $0.08 per second of video. Each session is billed at a minimum of 60 seconds runtime.

For more details, see [fal.ai pricing](https://fal.ai/pricing).

## Realtime API (WMA/WebRTC)

This endpoint publishes a WMA WebRTC contract. Open it with `fal.realtime.open`; do **not** call the session endpoint with `fal.run`, `fal.subscribe`, or the Queue API.

The browser negotiates through fal and then exchanges media with the model over WebRTC.

Client contract for the WebRTC session created by the linked OpenAPI operation.


### Install the experimental client

```bash
npm install @fal-ai/client@alpha @fal-ai/server-proxy@alpha
```

### Authentication and server proxy

Keep `FAL_KEY` on your server. Expose an authenticated proxy route to the browser. In a Next.js App Router application, create `app/api/fal/proxy/route.ts`:

```typescript
import { route } from "@fal-ai/server-proxy/nextjs";

export const { GET, POST, PUT } = route;
```

Protect that route with your application's authentication before deploying it.

### Open a browser session

```typescript
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/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({
  "protocol_version": 1,
  "prompt": "A continuous original live-action stream following a group of friends as they explore a new city.",
  "type": "configure",
  "prompt_version": 1
});

// Later, release the peer connection and network resources:
// await session.close();
```

## Media contract

Tracks are described from the browser's perspective.

### Browser sends to the model

None.

### Browser receives from the model

- `video` — optional
  - Settings: `{"frameRate":24}`
- `audio` — optional

## Client-to-model control messages

### Client configure message

- **Wire type**: `configure`
- **Payload**: `object`

- **`memory`** (`integer`, _optional_)
  Number of prior segment prompts retained as context for future prompt expansion.
  - Default: `12`
  - Constraints: minimum=1, maximum=50
- **`protocol_version`** (`integer`, _optional_)
  - Constant: `1`
- **`prompt`** (`string`, _required_)
  - Constraints: minLength=1, maxLength=50000
- **`seed`** (`integer | null`, _optional_)
  - Default: `null`
- **`type`** (`string`, _required_)
  - Constant: `"configure"`
- **`resolution`** (`string`, _optional_)
  - Default: `"768p"`
  - Values: `"480p"`, `"768p"`
- **`aspect_ratio`** (`string`, _optional_)
  - Default: `"16:9"`
  - Values: `"16:9"`, `"9:16"`, `"1:1"`
- **`prompt_version`** (`integer`, _required_)
  - Constraints: minimum=1
- Additional properties: not allowed

**Example**

```json
{
  "protocol_version": 1,
  "prompt": "A continuous original live-action stream following a group of friends as they explore a new city.",
  "type": "configure",
  "prompt_version": 1
}
```

### Client ping message

- **Wire type**: `ping`
- **Payload**: `object`

- **`type`** (`string`, _required_)
  - Constant: `"ping"`
- **`ts`** (`number`, _required_)
- Additional properties: not allowed

**Example**

```json
{
  "type": "ping",
  "ts": 0
}
```

### Client prompt message

- **Wire type**: `prompt`
- **Payload**: `object`

- **`prompt`** (`string`, _required_)
  - Constraints: minLength=1, maxLength=50000
- **`prompt_version`** (`integer`, _required_)
  - Constraints: minimum=1
- **`type`** (`string`, _required_)
  - Constant: `"prompt"`
- Additional properties: not allowed

**Example**

```json
{
  "prompt": "string",
  "prompt_version": 1,
  "type": "prompt"
}
```

### Client stop message

- **Wire type**: `stop`
- **Payload**: `object`

- **`type`** (`string`, _required_)
  - Constant: `"stop"`
- Additional properties: not allowed

**Example**

```json
{
  "type": "stop"
}
```

## Model-to-client control messages

### Server chunk message

- **Wire type**: `chunk`
- **Payload**: `object`

- **`buffer_depth_seconds`** (`number`, _required_)
  - Constraints: minimum=0
- **`scheduling_lead_ms`** (`number`, _required_)
- **`playback_seconds`** (`number`, _required_)
  - Constraints: exclusiveMinimum=0
- **`route`** (`string`, _required_)
  - Values: `"gorgonea"`, `"betelgeuse"`, `"regulus"`, `"unknown"`
- **`type`** (`string`, _required_)
  - Constant: `"chunk"`
- **`prompt_version`** (`integer`, _required_)
  - Constraints: minimum=1
- **`dispatch`** (`object`, _required_)
  - **`phases_ms`** (`object`, _required_)
    - Additional properties: number
  - **`overhead_ms`** (`number`, _required_)
    - Constraints: minimum=0
  - **`wall_ms`** (`number`, _required_)
    - Constraints: minimum=0
  - **`classified_ms`** (`number`, _required_)
    - Constraints: minimum=0
- **`chunk_index`** (`integer`, _required_)
  - Constraints: minimum=0
- **`next_generation_estimate_seconds`** (`number`, _required_)
  - Constraints: minimum=0
- **`generation_seconds`** (`number`, _required_)
  - Constraints: minimum=0
- **`requested_duration_seconds`** (`integer`, _required_)
  - Constraints: minimum=5, maximum=15
- **`scheduling_slack_ms`** (`number`, _required_)
- **`trimmed_context_frames`** (`integer`, _required_)
  - Constraints: minimum=0
- **`buffer_depth_chunks`** (`integer`, _required_)
  - Constraints: minimum=0
- **`generated_frame_count`** (`integer`, _required_)
  - Constraints: exclusiveMinimum=0

**Example**

```json
{
  "buffer_depth_seconds": 0,
  "scheduling_lead_ms": 0,
  "playback_seconds": 5e-324,
  "route": "gorgonea",
  "type": "chunk",
  "prompt_version": 1,
  "dispatch": {
    "phases_ms": {},
    "overhead_ms": 0,
    "wall_ms": 0,
    "classified_ms": 0
  },
  "chunk_index": 0,
  "next_generation_estimate_seconds": 0,
  "generation_seconds": 0,
  "requested_duration_seconds": 5,
  "scheduling_slack_ms": 0,
  "trimmed_context_frames": 0,
  "buffer_depth_chunks": 0,
  "generated_frame_count": 1
}
```

### Server chunk_metrics message

- **Wire type**: `chunk_metrics`
- **Payload**: `object`

- **`chunk_index`** (`integer`, _required_)
  - Constraints: minimum=0
- **`phases_ms`** (`object`, _required_)
  - Additional properties: number
- **`gauges`** (`object`, _required_)
  - Additional properties: number
- **`units`** (`string`, _required_)
  - Constant: `"ms"`
- **`route`** (`string`, _required_)
  - Values: `"gorgonea"`, `"betelgeuse"`, `"regulus"`, `"unknown"`
- **`type`** (`string`, _required_)
  - Constant: `"chunk_metrics"`
- **`chunk_consumable_ready_ms`** (`number | null`, _optional_)
  - Default: `null`
  - anyOf alternatives:
    1. `number`
      - Constraints: minimum=0
    2. `null`
- **`chunk_consumable_interval_ms`** (`number | null`, _optional_)
  - Default: `null`
  - anyOf alternatives:
    1. `number`
      - Constraints: minimum=0
    2. `null`

**Example**

```json
{
  "chunk_index": 0,
  "phases_ms": {},
  "gauges": {},
  "units": "ms",
  "route": "gorgonea",
  "type": "chunk_metrics"
}
```

### Server configured message

- **Wire type**: `configured`
- **Payload**: `object`

- **`memory`** (`integer | null`, _optional_)
  - Default: `null`
  - anyOf alternatives:
    1. `integer`
      - Constraints: minimum=1, maximum=50
    2. `null`
- **`chunk_duration`** (`integer | null`, _optional_)
  - Default: `null`
  - anyOf alternatives:
    1. `integer`
      - Constraints: minimum=5, maximum=15
    2. `null`
- **`acceleration`** (`string | null`, _optional_)
  - Default: `null`
  - anyOf alternatives:
    1. `string`
      - Values: `"none"`, `"regular"`
    2. `null`
- **`type`** (`string`, _required_)
  - Constant: `"configured"`
- **`has_initial_image`** (`boolean | null`, _optional_)
  - Default: `null`
- **`enable_safety_checker`** (`boolean`, _required_)
- **`resolution`** (`string | string | null`, _optional_)
  - Default: `null`
  - anyOf alternatives:
    1. `string`
      - Values: `"480p"`, `"544p"`, `"640p"`, `"704p"`, `"768p"`
    2. `string`
      - Values: `"480p"`, `"768p"`
    3. `null`
- **`prompt_version`** (`integer`, _required_)
  - Constraints: minimum=1
- **`aspect_ratio`** (`string | null`, _optional_)
  - Default: `null`
  - anyOf alternatives:
    1. `string`
      - Values: `"16:9"`, `"9:16"`, `"1:1"`
    2. `null`

**Example**

```json
{
  "type": "configured",
  "enable_safety_checker": true,
  "prompt_version": 1
}
```

### Server deadline_missed message

- **Wire type**: `deadline_missed`
- **Payload**: `object`

- **`behavior`** (`string`, _required_)
  - Constant: `"freeze_video_and_silence_audio_until_ready"`
- **`chunk_index`** (`integer`, _required_)
  - Constraints: minimum=0
- **`type`** (`string`, _required_)
  - Constant: `"deadline_missed"`
- **`late_by_seconds`** (`number`, _required_)
  - Constraints: minimum=0

**Example**

```json
{
  "behavior": "freeze_video_and_silence_audio_until_ready",
  "chunk_index": 0,
  "type": "deadline_missed",
  "late_by_seconds": 0
}
```

### Server error message

- **Wire type**: `error`
- **Payload**: `object`

- **`detail`** (`object[] | null`, _optional_)
  - Default: `null`
  - anyOf alternatives:
    1. `object[]`
      - Array items: `object`
    2. `null`
- **`code`** (`string`, _required_)
  - Values: `"content_policy"`, `"configuration_timeout"`, `"generation_failed"`, `"generation_timeout"`, `"immutable_settings"`, `"initialization_timeout"`, `"invalid_initial_image"`, `"invalid_message"`, `"not_configured"`, `"stale_prompt_version"`
- **`prompt_version`** (`integer | null`, _optional_)
  - Default: `null`
  - anyOf alternatives:
    1. `integer`
      - Constraints: minimum=1
    2. `null`
- **`type`** (`string`, _required_)
  - Constant: `"error"`
- **`error`** (`string`, _required_)

**Example**

```json
{
  "code": "content_policy",
  "type": "error",
  "error": "string"
}
```

### Server pong message

- **Wire type**: `pong`
- **Payload**: `object`

- **`client_ts`** (`number`, _required_)
- **`type`** (`string`, _required_)
  - Constant: `"pong"`

**Example**

```json
{
  "client_ts": 0,
  "type": "pong"
}
```

### Server prompt_applied message

- **Wire type**: `prompt_applied`
- **Payload**: `object`

- **`prompt_version`** (`integer`, _required_)
  - Constraints: minimum=1
- **`type`** (`string`, _required_)
  - Constant: `"prompt_applied"`

**Example**

```json
{
  "prompt_version": 1,
  "type": "prompt_applied"
}
```

### Server prompt_pending message

- **Wire type**: `prompt_pending`
- **Payload**: `object`

- **`prompt_version`** (`integer`, _required_)
  - Constraints: minimum=1
- **`type`** (`string`, _required_)
  - Constant: `"prompt_pending"`

**Example**

```json
{
  "prompt_version": 1,
  "type": "prompt_pending"
}
```

### Server prompt_rejected message

- **Wire type**: `prompt_rejected`
- **Payload**: `object`

- **`reason`** (`string`, _required_)
  - Constant: `"content_policy"`
- **`prompt_version`** (`integer`, _required_)
  - Constraints: minimum=1
- **`type`** (`string`, _required_)
  - Constant: `"prompt_rejected"`

**Example**

```json
{
  "reason": "content_policy",
  "prompt_version": 1,
  "type": "prompt_rejected"
}
```

### Server session_info message

- **Wire type**: `session_info`
- **Payload**: `object`

- **`protocol_version`** (`integer`, _optional_)
  - Constant: `1`
- **`prompt_deck_size`** (`integer`, _optional_)
  - Constant: `3`
- **`chunk_seconds`** (`integer`, _optional_)
  - Constant: `10`
- **`min_chunk_duration`** (`integer`, _optional_)
  - Constant: `5`
- **`resolutions`** (`string[]`, _optional_)
  - Default: `["480p","768p"]`
  - Array items: `string`
    - Values: `"480p"`, `"768p"`
- **`server_message_types`** (`string[]`, _optional_)
  - Default: `["chunk","chunk_metrics","configured","deadline_missed","error","pong","prompt_applied","prompt_pending","prompt_rejected","session_info","session_metrics","stream_exhausted"]`
  - Array items: `string`
    - Values: `"chunk"`, `"chunk_metrics"`, `"configured"`, `"deadline_missed"`, `"error"`, `"pong"`, `"prompt_applied"`, `"prompt_pending"`, `"prompt_rejected"`, `"session_info"`, `"session_metrics"`, `"stream_exhausted"`
- **`app`** (`string`, _optional_)
  - Constant: `"minimax-h3-max-director"`
- **`accelerations`** (`string[]`, _optional_)
  - Default: `["none","regular"]`
  - Array items: `string`
    - Values: `"none"`, `"regular"`
- **`type`** (`string`, _required_)
  - Constant: `"session_info"`
- **`continuation_playback_seconds`** (`number`, _optional_)
  - Default: `8.5`
- **`client_message_types`** (`string[]`, _optional_)
  - Default: `["configure","ping","prompt","stop"]`
  - Array items: `string`
    - Values: `"configure"`, `"ping"`, `"prompt"`, `"stop"`
- **`default_memory`** (`integer`, _optional_)
  - Constant: `12`
- **`max_chunk_duration`** (`integer`, _optional_)
  - Constant: `15`
- **`continuation_context_frames`** (`integer`, _optional_)
  - Constant: `39`
- **`prompt_expander`** (`string`, _optional_)
  - Constant: `"fast"`
- **`default_chunk_duration`** (`integer`, _optional_)
  - Constant: `10`
- **`controller_machine_type`** (`string`, _optional_)
  - Constant: `"XL"`
- **`backend_selection`** (`string`, _optional_)
  - Constant: `"minimax-h3-turbo-balancer"`
- **`default_acceleration`** (`string`, _optional_)
  - Constant: `"regular"`
- **`max_memory`** (`integer`, _optional_)
  - Constant: `50`
- **`min_memory`** (`integer`, _optional_)
  - Constant: `1`
- **`audio_sample_rate`** (`integer`, _optional_)
  - Constant: `32000`
- **`prompt_context_segments`** (`integer`, _optional_)
  - Constant: `12`
- **`one_session_per_machine`** (`boolean`, _optional_)
  - Constant: `true`
- **`aspect_ratios`** (`string[]`, _optional_)
  - Default: `["16:9","9:16","1:1"]`
  - Array items: `string`
    - Values: `"16:9"`, `"9:16"`, `"1:1"`
- **`fps`** (`integer`, _optional_)
  - Constant: `24`
- **`max_session_seconds`** (`number | null`, _optional_)
  - Default: `null`

**Example**

```json
{
  "protocol_version": 1,
  "prompt_deck_size": 3,
  "chunk_seconds": 10,
  "min_chunk_duration": 5,
  "app": "minimax-h3-max-director",
  "type": "session_info",
  "default_memory": 12,
  "max_chunk_duration": 15,
  "continuation_context_frames": 39,
  "prompt_expander": "fast",
  "default_chunk_duration": 10,
  "controller_machine_type": "XL",
  "backend_selection": "minimax-h3-turbo-balancer",
  "default_acceleration": "regular",
  "max_memory": 50,
  "min_memory": 1,
  "audio_sample_rate": 32000,
  "prompt_context_segments": 12,
  "one_session_per_machine": true,
  "fps": 24
}
```

### Server session_metrics message

- **Wire type**: `session_metrics`
- **Payload**: `object`

- **`final`** (`boolean`, _optional_)
  - Default: `false`
- **`gauges`** (`object`, _required_)
  - Additional properties: number
- **`units`** (`string`, _required_)
  - Constant: `"ms"`
- **`history_size`** (`integer`, _required_)
  - Constraints: minimum=0
- **`type`** (`string`, _required_)
  - Constant: `"session_metrics"`
- **`history_limit`** (`integer`, _required_)
  - Constraints: minimum=1
- **`session_wall_ms`** (`number`, _required_)
  - Constraints: minimum=0
- **`phases`** (`object`, _required_)
  - Additional properties: object
    - **`p50_ms`** (`number`, _required_)
      - Constraints: minimum=0
    - **`total_ms`** (`number`, _required_)
      - Constraints: minimum=0
    - **`max_ms`** (`number`, _required_)
      - Constraints: minimum=0
    - **`p95_ms`** (`number`, _required_)
      - Constraints: minimum=0
    - **`count`** (`integer`, _required_)
      - Constraints: minimum=0

**Example**

```json
{
  "gauges": {},
  "units": "ms",
  "history_size": 0,
  "type": "session_metrics",
  "history_limit": 1,
  "session_wall_ms": 0,
  "phases": {}
}
```

### Server stream_exhausted message

- **Wire type**: `stream_exhausted`
- **Payload**: `object`

- **`reason`** (`string`, _required_)
  - Values: `"stopped"`, `"session_limit"`
- **`chunks`** (`integer`, _required_)
  - Constraints: minimum=0
- **`type`** (`string`, _required_)
  - Constant: `"stream_exhausted"`

**Example**

```json
{
  "reason": "stopped",
  "chunks": 0,
  "type": "stream_exhausted"
}
```

## Additional Resources

### Documentation

- [Model Playground](https://fal.ai/models/minimax/h3-max/director)
- [API Documentation](https://fal.ai/models/minimax/h3-max/director/api)
- [OpenAPI Schema](https://fal.ai/api/openapi/queue/openapi.json?endpoint_id=minimax/h3-max/director)
- [AsyncAPI Contract](https://fal.ai/api/apps/fal-ai/minimax-h3-max-director/asyncapi.json)

### fal.ai Platform

- [Platform Documentation](https://fal.ai/docs/documentation)
- [Python Client](https://fal.ai/docs/api-reference/client-libraries/python)
- [JavaScript Client](https://fal.ai/docs/api-reference/client-libraries/javascript)

### Other agent-readable surfaces

This file covers one model. To find anything else:

- [Platform overview](https://fal.ai/llms.txt): Entry points and representative endpoint IDs
- [Documentation index](https://fal.ai/docs/llms.txt): Every documentation page
- [Full documentation text](https://fal.ai/docs/llms-full.txt): The whole documentation inlined
- Any other model: `https://fal.ai/models/<endpoint-id>/llms.txt`
