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

# Recording

> What gets saved during a session, how each action is paired with what caused it, and how it becomes a dataset.

A session produces two things: motion now, and a dataset later. The two want
opposite things, so recording happens away from the control path.

## How to record

Give the follower a path and it records while you drive.

```python theme={null}
follower = MyArm(MEETING_ID, record="./sessions")
```

That attaches a recorder when the session starts and closes it when the session
stops. To turn it on and off yourself, leave `record=` out and call the methods
directly.

| Call | What it does |
| - | - |
| `record="./sessions"` | attach a recorder for the whole session |
| `start_recording(root)` | attach one yourself, later |
| `start_episode(task)` | begin one demonstration |
| `end_episode(success)` | close it, and say whether it worked |
| `stop_recording()` | detach the recorder and close the files |

Both sides can record. Everything above works the same on a
[Leader](/robotics/api-reference/python/leader#recording), which is useful when the
person driving is not on the same machine as the arm.

<Note>
  Recording never blocks the control path. Control keeps only what it needs and
  discards the rest, which is right for moving a robot and wrong for a dataset.
  If the disk cannot keep up, rows are dropped rather than allowed to stall the
  loop, and every drop is counted into `episode.json`. See
  [Recording format](/robotics/guides/recording-format#recording-is-best-effort).
</Note>

## Episodes

An episode is one demonstration. By default the deadman marks the boundary:
squeeze to start, release to end.

```python theme={null}
follower.auto_episode = False              # take the boundaries yourself

follower.start_episode("pick up the cube")
# ... drive ...
follower.end_episode(success=True)
```

`success` is `True`, `False`, or `None` for not judged, so you can decide later
whether failures are noise or negative examples.

## Where it is kept

**On the robot.** The path you passed. The follower already holds the commanded
value, the value read back and the camera frames, so nothing is lost and every
timestamp comes from one machine.

**In cloud storage.** Pass `cloud_recording=True` and the same episodes are
uploaded as well, paired with the local copy by episode id.

They go to the storage configured for your account, set up on the
[API keys page](https://app.videosdk.live/api-keys). See
[Cloud recording](/robotics/guides/cloud-recording).

## Export

A recorded session becomes a LeRobot dataset with `zeroruntime.teleops.export` for
the join and a writer script from the examples repo.

<Card title="Exporting datasets" icon="table" href="/robotics/guides/exporting-datasets" horizontal>
  The functions, the commands, and the correlation quality to check first.
</Card>

## Related

<CardGroup cols={2}>
  <Card title="Recording format" icon="folder-tree" href="/robotics/guides/recording-format">
    The files a session writes, and the counters to check before training.
  </Card>

  <Card title="Sync" icon="film" href="/robotics/concepts/sync">
    Matching video to joint readings.
  </Card>

  <Card title="Types" icon="eye" href="/robotics/api-reference/python/observation">
    Every id and what creates it.
  </Card>

  <Card title="Cloud recording" icon="cloud" href="/robotics/guides/cloud-recording">
    Uploading episodes to your own storage alongside the local copy.
  </Card>
</CardGroup>


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