# Eden Live 14B Video

> Real-time generative rendering from any reference using VAST's Eden Live 14B


## Overview

- **Endpoint**: `https://fal.run/vast/eden-live-14b-video`
- **Model ID**: `vast/eden-live-14b-video`
- **Category**: video-to-video
- **Kind**: inference


## Pricing

Sessions cost $0.01 per second of video generated, with a minimum of 10 billable seconds ($0.10) per session.

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 deviceStream = await navigator.mediaDevices.getUserMedia({
  "video": {
    "frameRate": 16,
    "height": 480,
    "width": 832
  },
  "audio": false
});
const localStream = deviceStream;

const session = fal.realtime.open(wma("vast/eden-live-14b-video"), {
  receive: [
    "video"
  ],
  localStream,
  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({
  "prompt": "Change to anime style",
  "enable_prompt_expansion": true,
  "type": "configure"
});

// Later, release the peer connection and network resources:
// localStream.getTracks().forEach((track) => track.stop());
// await session.close();
```


## Media contract

Tracks are described from the browser's perspective.

### Browser sends to the model

- `video` — required
  - Constraints: `{"frameRate":16,"height":480,"width":832}`

### Browser receives from the model

- `video` — optional
  - Settings: `{"frameRate":16,"height":480,"width":832}`

## Client-to-model control messages

### Set conditioning

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

Set the session's conditioning, once per connection; await ``configured``.

Without ``image_url`` the world anchors on a reference generated from the
newest input frame and the prompt (FLUX.2 [klein] 4B edit), or on that
frame itself when generation fails.

- **`prompt`** (`string | null`, _optional_)
  What the input video should look like. Defaults to a generic photoreal prompt.
  - Default: `null`
  - anyOf alternatives:
    1. `string`
      - Constraints: maxLength=2000
    2. `null`
- **`image_url`** (`string | null`, _optional_)
  Rendering of the input's first frame in the target look (URL, or a data URI under ~45 KB); anchors the generated world. Without it, one is generated from the newest input frame and the prompt.
  - Default: `null`
  - anyOf alternatives:
    1. `string`
      - Constraints: maxLength=60000
    2. `null`
- **`enable_prompt_expansion`** (`boolean`, _optional_)
  Rewrite the scene description (and later prompt changes) into a detailed one with an LLM, using the reference image when given. Adds about a second to session start and to each prompt change.
  - Default: `false`
- **`seed`** (`integer | null`, _optional_)
  Noise seed; the same inputs and seed reproduce the output.
  - Default: `null`
  - anyOf alternatives:
    1. `integer`
      - Constraints: minimum=0, maximum=2147483647
    2. `null`
- **`type`** (`string`, _required_)
  - Constant: `"configure"`
- Additional properties: not allowed

**Example**

```json
{
  "prompt": "Change to anime style",
  "enable_prompt_expansion": true,
  "type": "configure"
}
```

### Client ping message

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

Latency probe; the server echoes ``ts`` back in a ``pong`` payload.

- **`ts`** (`number | null`, _optional_)
  - Default: `null`
- **`type`** (`string`, _required_)
  - Constant: `"ping"`

**Example**

```json
{
  "type": "ping"
}
```

### Update prompt

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

Change the scene description; applied at the next chunk boundary.

- **`prompt`** (`string`, _required_)
  Text the model renders the scene with. Keeps the current world.
  - Constraints: minLength=1, maxLength=2000
- **`type`** (`string`, _required_)
  - Constant: `"prompt"`
- Additional properties: not allowed

**Example**

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

### Restart

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

Restart generation from a new anchor; unset fields keep their values,
and an explicit null clears ``image_url`` or ``seed``.

The world is re-anchored on a reference generated from the newest input
frame unless ``image_url`` is set.

- **`prompt`** (`string | null`, _optional_)
  What the input video should look like. Defaults to a generic photoreal prompt.
  - Default: `null`
  - anyOf alternatives:
    1. `string`
      - Constraints: maxLength=2000
    2. `null`
- **`image_url`** (`string | null`, _optional_)
  Rendering of the input's first frame in the target look (URL, or a data URI under ~45 KB); anchors the generated world. Without it, one is generated from the newest input frame and the prompt.
  - Default: `null`
  - anyOf alternatives:
    1. `string`
      - Constraints: maxLength=60000
    2. `null`
- **`seed`** (`integer | null`, _optional_)
  Noise seed; the same inputs and seed reproduce the output.
  - Default: `null`
  - anyOf alternatives:
    1. `integer`
      - Constraints: minimum=0, maximum=2147483647
    2. `null`
- **`enable_prompt_expansion`** (`boolean | null`, _optional_)
  - Default: `null`
- **`type`** (`string`, _required_)
  - Constant: `"reset"`
- Additional properties: not allowed

**Example**

```json
{
  "type": "reset"
}
```

### End session

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

End the session.

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

**Example**

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

## Model-to-client control messages

### Server configured message

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

- **`game`** (`object | null`, _optional_)
  - Default: `null`
  - anyOf alternatives:
    1. `object`
      - **`description`** (`string`, _required_)
      - **`thumbnail_url`** (`string | null`, _optional_)
        - Default: `null`
      - **`prompt`** (`string`, _required_)
      - **`instructions`** (`string[]`, _required_)
        - Array items: `string`
      - **`title`** (`string`, _required_)
      - **`controls`** (`object[]`, _required_)
        - Array items: `object`
          - **`key`** (`string`, _required_)
          - **`command`** (`string | null`, _optional_)
            Semantic command name.
            - Default: `null`
          - **`label`** (`string`, _required_)
          - **`hold`** (`boolean`, _optional_)
            - Default: `true`
      - **`actions`** (`string[]`, _required_)
        - Array items: `string`
      - **`id`** (`string`, _required_)
    2. `null`
- **`type`** (`string`, _required_)
  - Constant: `"configured"`

**Example**

```json
{
  "type": "configured"
}
```

### Server error message

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

- **`retryable`** (`boolean | null`, _optional_)
  - Default: `null`
- **`type`** (`string`, _required_)
  - Constant: `"error"`
- **`error`** (`string`, _required_)

**Example**

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

### Server pong message

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

Reply to a ``ping``, echoing the client's timestamp for RTT measurement.

The echoed timestamp has two wire spellings: apps that handle ``ping``
themselves echo ``ts``; the fallback handler in
:class:`registry.wma.sdk.Session` replies with ``client_ts``. Clients read
whichever is present. ``server_ts`` is the (unsynchronized) runner clock; it
only shows how the round trip divides once the client has an offset estimate.

- **`client_ts`** (`number | null`, _optional_)
  - Default: `null`
- **`server_ts`** (`number | null`, _optional_)
  - Default: `null`
- **`ts`** (`number | null`, _optional_)
  - Default: `null`
- **`type`** (`string`, _required_)
  - Constant: `"pong"`

**Example**

```json
{
  "type": "pong"
}
```

### Server prompt_applied message

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

- **`type`** (`string`, _required_)
  - Constant: `"prompt_applied"`

**Example**

```json
{
  "type": "prompt_applied"
}
```

### Server reset_applied message

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

- **`game`** (`object | null`, _optional_)
  - Default: `null`
  - anyOf alternatives:
    1. `object`
      - **`description`** (`string`, _required_)
      - **`thumbnail_url`** (`string | null`, _optional_)
        - Default: `null`
      - **`prompt`** (`string`, _required_)
      - **`instructions`** (`string[]`, _required_)
        - Array items: `string`
      - **`title`** (`string`, _required_)
      - **`controls`** (`object[]`, _required_)
        - Array items: `object`
          - **`key`** (`string`, _required_)
          - **`command`** (`string | null`, _optional_)
            Semantic command name.
            - Default: `null`
          - **`label`** (`string`, _required_)
          - **`hold`** (`boolean`, _optional_)
            - Default: `true`
      - **`actions`** (`string[]`, _required_)
        - Array items: `string`
      - **`id`** (`string`, _required_)
    2. `null`
- **`type`** (`string`, _required_)
  - Constant: `"reset_applied"`

**Example**

```json
{
  "type": "reset_applied"
}
```

### Server session_info message

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

- **`info`** (`object`, _required_)
- **`session`** (`string`, _required_)
  - Values: `"video"`, `"game"`
- **`type`** (`string`, _required_)
  - Constant: `"session_info"`

**Example**

```json
{
  "info": {},
  "session": "video",
  "type": "session_info"
}
```

### Server stats message

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

- **`prompt_ms`** (`number | null`, _optional_)
  Per-chunk prompt update time with dynamic_prompt, unchanged chunks included (moving average).
  - Default: `null`
- **`chunk`** (`integer`, _required_)
- **`pipelined`** (`boolean | null`, _optional_)
  The next chunk renders while this one generates (throughput mode).
  - Default: `null`
- **`render_ms`** (`number | null`, _optional_)
  Game render time per chunk (moving average).
  - Default: `null`
- **`realtime_factor`** (`number`, _required_)
  Generated frames per second / target fps.
- **`generation_fps`** (`number`, _required_)
- **`type`** (`string`, _required_)
  - Constant: `"stats"`
- **`chunk_ms`** (`number`, _required_)
- **`latency_ms`** (`number | null`, _optional_)
  Input or control capture to frame handoff, median.
  - Default: `null`
- **`input_latency_ms`** (`number | null`, _optional_)
  Game control message arrival to the handoff of the first frame it changes, median.
  - Default: `null`
- **`loop_lag_ms`** (`number | null`, _optional_)
  Server event-loop lag, p95 over the stats window.
  - Default: `null`
- **`generate_ms`** (`number | null`, _optional_)
  Model time per chunk (moving average).
  - Default: `null`
- **`queue_frames`** (`integer`, _required_)
- **`billable_units`** (`number | null`, _optional_)
  Seconds of video billed so far this session (queued for playback); the final total settles when the session closes.
  - Default: `null`

**Example**

```json
{
  "chunk": 0,
  "realtime_factor": 0,
  "generation_fps": 0,
  "type": "stats",
  "chunk_ms": 0,
  "queue_frames": 0
}
```

### Server stream_exhausted message

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

The model has no more frames to send and the current peer is closing.
Clients must negotiate a new session to continue.

- **`type`** (`string`, _required_)
  - Constant: `"stream_exhausted"`

**Example**

```json
{
  "type": "stream_exhausted"
}
```

## Additional Resources

### Documentation

- [Model Playground](https://fal.ai/models/vast/eden-live-14b-video)
- [API Documentation](https://fal.ai/models/vast/eden-live-14b-video/api)
- [OpenAPI Schema](https://fal.ai/api/openapi/queue/openapi.json?endpoint_id=vast/eden-live-14b-video)
- [AsyncAPI Contract](https://fal.ai/api/apps/fal-ai/eden-live-14b-video/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`
