> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zeroruntime.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Installation

> Install zeroruntime-teleops and the optional packages for your setup.

## Requirements

| What you install | Python |
| - | - |
| `zeroruntime-teleops` | 3.10 and above |
| `zeroruntime-teleops[lerobot]` | 3.12 and above |
| `zeroruntime-teleops[ros2]` | 3.12, the Python ROS 2 Jazzy runs on |

3.12 is the reference version.

## Install

```bash theme={null}
pip install zeroruntime-teleops
```

That is everything needed to join a room, capture cameras and record a
session, on both machines.

The package is [`zeroruntime-teleops` on PyPI](https://pypi.org/project/zeroruntime-teleops/).

## Additional setup

### LeRobot

```bash theme={null}
pip install "zeroruntime-teleops[lerobot]"
```

Adds the adapters that wrap an existing LeRobot `Robot` and `Teleoperator`.
See [LeRobot](/robotics/integrations/lerobot) for the setup, and LeRobot's own
[installation guide](https://huggingface.co/docs/lerobot/installation)
for the library itself.

### ROS 2

```bash theme={null}
pip install "zeroruntime-teleops[ros2]"
```

The extra is intentionally empty: `rclpy`, `sensor_msgs` and `std_srvs` are not
on PyPI at all, they come from your ROS distribution. It exists so the command
above resolves rather than erroring, and the real work is installing into the
same interpreter ROS 2 runs on. There is nothing to build: the bridge ships as
two commands, `zrt-teleops-ros2-leader` and `zrt-teleops-ros2-follower`.

New to ROS 2? Follow the
[official installation guide](https://docs.ros.org/en/jazzy/Installation.html)
first, then see [ROS 2](/robotics/integrations/ros2) for the bridge setup.

## Environment

The SDK reads the following environment variables.

| Variable | Purpose | Default |
| - | - | - |
| `ZERORUNTIME_AUTH_TOKEN` | Your access token | required |
| `ZERORUNTIME_MEETING_ID` | The room both ends join. The ROS 2 bridge also reads `MEETING_ID` | a new room is created (the ROS 2 bridge requires it) |
| `ZERORUNTIME_CAMERAS` | Which cameras the follower streams when your code passes no `cameras=`: names from `python -m zeroruntime.teleops.devices`, comma-separated, or `none`. On macOS the names are numbers like `0,1`, and you need `pip install opencv-python` | every USB camera (every camera on macOS) |
| `SIGNALING_BASE_URL` | Signaling host | `api.videosdk.live` |
| `ZERORUNTIME_API_BASE` | API host for room creation and cloud recording. Read per call | `api.videosdk.live` |

```bash theme={null}
export ZERORUNTIME_AUTH_TOKEN="your-token-here"
export ZERORUNTIME_MEETING_ID="abcd-efgh-ijkl"
```

Get a token from [the dashboard](https://app.videosdk.live/signup).

<Note>
  Set `ZERORUNTIME_MEETING_ID` so both ends join the same room. Without it each
  side creates its own room and joins successfully into silence.
</Note>

## Find your devices

Run this on the robot to list its cameras and serial ports. You will need these
paths when you set up the follower:

```bash theme={null}
python -m zeroruntime.teleops.devices
```

```
cameras (2)
  /dev/video0   platform-3610000.usb-usb-0:2.2:1.0-video-index0
  /dev/video2   platform-3610000.usb-usb-0:2.4:1.0-video-index0

serial (2)
  /dev/ttyACM0  platform-3610000.usb-usb-0:2.1:1.0-port0
  /dev/ttyACM1  platform-3610000.usb-usb-0:2.3:1.0-port0

Put this in .env:
  ZERORUNTIME_CAMERAS=platform-3610000.usb-usb-0:2.2:1.0-video-index0,platform-3610000.usb-usb-0:2.4:1.0-video-index0
```

Use the names on the right. Names like `/dev/video0` can change after a reboot,
while the longer name stays with the physical port. The last line picks these
cameras: copy it into your `.env`.

<Note>
  On macOS, cameras are listed by number (`0`, `1`, ...) and serial ports as
  `/dev/cu.*`. Camera numbers change when you plug a camera in or out, so run it
  again after.
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.