# Flux 3 Action

> FLUX 3 Action turns what the robot sees into what it does next. Give it the scene camera image, the wrist camera image, the current SO-101 joint state (shoulder pan, shoulder lift, elbow flex, wrist flex, wrist roll, gripper) and a plain-language instruction such as "Pick up the yellow cube and place it inside the black rectangle". It returns a chunk of 42 target joint positions at 30 Hz, that is 1.4 s of motion. In a control loop, execute the first 32 steps (about 1 s), then call again with fresh images and joint state.


## Overview

- **Endpoint**: `https://fal.run/fal-ai/flux-3-action/so101`
- **Model ID**: `fal-ai/flux-3-action/so101`
- **Category**: video-to-video
- **Kind**: inference
**Tags**: robotic, arm



## Pricing

Pricing can change for this endpoint.  Your request will cost $0.003 per compute second. A typical call (one 42-step action chunk) is billed about 0.5 to 2 s of compute, so roughly $0.0015 to $0.006 per call, or about 1 s of robot motion.

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

## API Information

This model can be used via our HTTP API or more conveniently via our client libraries.
See the input and output schema below, as well as the usage examples.


### Input Schema

The API accepts the following input parameters:


- **`prompt`** (`string`, _required_):
  Natural-language task instruction for the robot.
  - Examples: "place the box in the container"

- **`scene_image_url`** (`string`, _required_):
  Current frame from the fixed scene camera (tiled left). Resized to 256x256.
  - Examples: "https://v3b.fal.media/files/b/0aaba0cf/rbESQ2h5nozh5K8Ms1FDm_scene.png"

- **`wrist_image_url`** (`string`, _required_):
  Current frame from the wrist camera (tiled right). Resized to 256x256.
  - Examples: "https://v3b.fal.media/files/b/0aaba0cf/qyaj49X3PZc70wJwz90f1_wrist.png"

- **`state`** (`list<float>`, _required_):
  Measured state: shoulder pan, shoulder lift, elbow flex, wrist flex, wrist roll (degrees), gripper (percent).
  - Array of float
  - Examples: [-18.94,134.52,120.15,28.3,-32.17,27.02]

- **`state_history`** (`list<list<float>>`, _optional_):
  Measured states at the 7 control ticks (30 Hz) before `state`, oldest first. Requires `command_history`. Omit for a fresh episode.
  - Array of list<float>

- **`command_history`** (`list<list<float>>`, _optional_):
  Absolute commands in effect at each of the 8 observation ticks, oldest first; the last row is the most recent command sent. Requires `state_history`.
  - Array of list<float>

- **`history_scene_image_url`** (`string`, _optional_):
  Scene frame from the oldest history tick (7 ticks before now). Requires `state_history`. Defaults to the current frame.

- **`history_wrist_image_url`** (`string`, _optional_):
  Wrist frame from the oldest history tick. Requires `state_history`.

- **`num_inference_steps`** (`integer`, _optional_):
  Euler denoising steps. The checkpoint was validated at 4. Default value: `4`
  - Default: `4`
  - Range: `1` to `8`

- **`guidance_scale`** (`float`, _optional_):
  Classifier-free guidance on video and action; 1.0 disables CFG. Default value: `3`
  - Default: `3`
  - Range: `1` to `10`

- **`seed`** (`integer`, _optional_):
  Sampling seed. Omit for a random seed; the reference evaluation seed is 0 for DROID and 42 for SO-101.



**Required Parameters Example**:

```json
{
  "prompt": "place the box in the container",
  "scene_image_url": "https://v3b.fal.media/files/b/0aaba0cf/rbESQ2h5nozh5K8Ms1FDm_scene.png",
  "wrist_image_url": "https://v3b.fal.media/files/b/0aaba0cf/qyaj49X3PZc70wJwz90f1_wrist.png",
  "state": [
    -18.94,
    134.52,
    120.15,
    28.3,
    -32.17,
    27.02
  ]
}
```

**Full Example**:

```json
{
  "prompt": "place the box in the container",
  "scene_image_url": "https://v3b.fal.media/files/b/0aaba0cf/rbESQ2h5nozh5K8Ms1FDm_scene.png",
  "wrist_image_url": "https://v3b.fal.media/files/b/0aaba0cf/qyaj49X3PZc70wJwz90f1_wrist.png",
  "state": [
    -18.94,
    134.52,
    120.15,
    28.3,
    -32.17,
    27.02
  ],
  "num_inference_steps": 4,
  "guidance_scale": 3
}
```


### Output Schema

The API returns the following output format:

- **`actions`** (`list<list<float>>`, _required_):
  Predicted action chunk, one row per control step in time order. DROID: 32x8 absolute joint targets (rad) plus gripper closed fraction at 15 Hz. SO-101: 42x6 absolute commands (deg, gripper %) at 30 Hz. Not clipped: enforce joint, velocity and workspace limits on the robot.
  - Array of list<float>

- **`action_labels`** (`list<string>`, _required_):
  Name of each action column.
  - Array of string

- **`action_hz`** (`float`, _required_):
  Control rate of the action rows.

- **`execute_steps`** (`integer`, _required_):
  Execute this many leading actions, then request a new chunk.

- **`seed`** (`integer`, _required_):
  Seed used for sampling.

- **`timings`** (`Timings`, _required_):
  Server-side timings in seconds.



**Example Response**:

```json
{}
```


## Usage Examples

### cURL

```bash
curl --request POST \
  --url https://fal.run/fal-ai/flux-3-action/so101 \
  --header "Authorization: Key $FAL_KEY" \
  --header "Content-Type: application/json" \
  --data '{
     "prompt": "place the box in the container",
     "scene_image_url": "https://v3b.fal.media/files/b/0aaba0cf/rbESQ2h5nozh5K8Ms1FDm_scene.png",
     "wrist_image_url": "https://v3b.fal.media/files/b/0aaba0cf/qyaj49X3PZc70wJwz90f1_wrist.png",
     "state": [
       -18.94,
       134.52,
       120.15,
       28.3,
       -32.17,
       27.02
     ]
   }'
```

### Python

Ensure you have the Python client installed:

```bash
pip install fal-client
```

Then use the API client to make requests:

```python
import fal_client

def on_queue_update(update):
    if isinstance(update, fal_client.InProgress):
        for log in update.logs:
           print(log["message"])

result = fal_client.subscribe(
    "fal-ai/flux-3-action/so101",
    arguments={
        "prompt": "place the box in the container",
        "scene_image_url": "https://v3b.fal.media/files/b/0aaba0cf/rbESQ2h5nozh5K8Ms1FDm_scene.png",
        "wrist_image_url": "https://v3b.fal.media/files/b/0aaba0cf/qyaj49X3PZc70wJwz90f1_wrist.png",
        "state": [-18.94, 134.52, 120.15, 28.3, -32.17, 27.02]
    },
    with_logs=True,
    on_queue_update=on_queue_update,
)
print(result)
```

### JavaScript

Ensure you have the JavaScript client installed:

```bash
npm install --save @fal-ai/client
```

Then use the API client to make requests:

```javascript
import { fal } from "@fal-ai/client";

const result = await fal.subscribe("fal-ai/flux-3-action/so101", {
  input: {
    prompt: "place the box in the container",
    scene_image_url: "https://v3b.fal.media/files/b/0aaba0cf/rbESQ2h5nozh5K8Ms1FDm_scene.png",
    wrist_image_url: "https://v3b.fal.media/files/b/0aaba0cf/qyaj49X3PZc70wJwz90f1_wrist.png",
    state: [-18.94, 134.52, 120.15, 28.3, -32.17, 27.02]
  },
  logs: true,
  onQueueUpdate: (update) => {
    if (update.status === "IN_PROGRESS") {
      update.logs.map((log) => log.message).forEach(console.log);
    }
  },
});
console.log(result.data);
console.log(result.requestId);
```


## Additional Resources

### Documentation

- [Model Playground](https://fal.ai/models/fal-ai/flux-3-action/so101)
- [API Documentation](https://fal.ai/models/fal-ai/flux-3-action/so101/api)
- [OpenAPI Schema](https://fal.ai/api/openapi/queue/openapi.json?endpoint_id=fal-ai/flux-3-action/so101)

### 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`
