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

# Recording and time

> Recording identity, the clock, the task and time-segmented annotations.

## `recording`

```json theme={null}
"recording": {
  "id": "episode-000042",
  "clock": "log_time",
  "t0_ns": 1712345678000000000,
  "description": "Kitchen teleoperation, operator 3",
  "task": {"instruction": "Pick up the plate and wipe it with the eraser."},
  "segments": [{"start_s": 0.0, "end_s": 21.9, "text": "Pick up the plate.", "label": "subtask"}],
  "platform": {"kind": "manipulator", "parts": ["…"]}
}
```

| Field | Type | Required | Meaning |
| - | - | - | - |
| `id` | string | yes | Your stable identifier for the recording. It MUST stay the same when you re-export the same recording, because it is the key for attaching a later recording (e.g. LiDAR) to this one. |
| `clock` | `"log_time"` \| `"publish_time"` | yes | Which MCAP message timestamp is authoritative. |
| `t0_ns` | integer | yes | The earliest timestamp in the recording, in nanoseconds. All recording-relative times (`segments`) count from it. |
| `description` | string | no | Free text. |
| `task` | object | no | What the recording was made to do. See [Task](#task). |
| `segments` | array | no | Annotated spans of the recording. See [Segments](#segments). |
| `platform` | object | yes | What the recording is of. See [Body and parts](/mcap-spec/body-and-parts). |

## Clock

* All channels in a recording MUST share **one clock**. Do not mix time sources, e.g. a camera on
  host time and a CAN bus on its own counter.
* Timestamps MUST be **non-decreasing within each channel**. Messages SHOULD be written in
  non-decreasing `log_time` order across the whole file: merge your channels by time before writing.
* `t0_ns` MUST be the earliest timestamp in the file.
* Timestamps SHOULD be **absolute Unix epoch nanoseconds**. A relative clock is accepted with a
  warning, but a recording on a relative clock cannot be aligned with another recording.
  Preflight warns when `t0_ns` is below 10<sup>18</sup> (before 2001), which usually means a
  relative clock or microseconds that were never scaled.

<Note>
  Write the **same nanosecond time** to a message's `log_time`, its `publish_time` and its own
  `timestamp` field. Signals, keypoints and GPS fixes are timed by their MCAP `log_time`; the
  `timestamp` inside a `nomadic.Signal` or `nomadic.Skeleton` is not read. Keeping all three equal
  removes any ambiguity.
</Note>

## Task

One instruction for the whole recording goes in `recording.task`:

```json theme={null}
"task": {
  "instruction": "Pick up the plate and wipe it with the eraser.",
  "scene": "A plate with marks and an eraser are on the table.",
  "success_criteria": "The marks are removed and both objects are back on the table."
}
```

| Field | Type | Required | Meaning |
| - | - | - | - |
| `instruction` | string | yes | The instruction, in natural language. On a `vehicle` it is the **route** driven (e.g. "Go straight for 150 m and turn right at the traffic light"); on any other body it is the **task** performed. |
| `scene` | string | no | The objects and layout the task starts from. |
| `success_criteria` | string | no | What counts as the task done. |

Every present field MUST be a non-empty string. Text is kept as written.

For an instruction that **changes during** the recording, such as turn-by-turn navigation, use a
[`navigation_instruction` signal](/mcap-spec/signals#navigation-instructions) instead.

## Segments

Annotations of spans of the recording, such as the subtasks of its task, go in
`recording.segments`, one entry per span:

```json theme={null}
"segments": [
  {"start_s": 0.0,  "end_s": 21.9, "text": "Pick up the plate with the left hand.",
   "label": "subtask", "skill": "pick", "id": "subtask-001"},
  {"start_s": 21.9, "end_s": 24.3, "text": "Pick up the eraser with the right hand.",
   "label": "subtask", "skill": "pick", "id": "subtask-002"}
]
```

| Field | Type | Required | Meaning |
| - | - | - | - |
| `start_s` | number | yes | Seconds from `recording.t0_ns`, ≥ 0. |
| `end_s` | number | yes | Seconds from `recording.t0_ns`, end exclusive. MUST be greater than `start_s`. |
| `text` | string | yes | The annotation, non-empty. |
| `label` | string | no | The annotation type, e.g. `subtask`. |
| `skill` | string | no | A compact skill label, e.g. `pick`, `place`, `wipe`. |
| `id` | string | no | Your identifier for the segment. |

* Segments MAY overlap and need not cover the whole recording.
* Segments are ground-truth annotations. They are kept with the recording and are never used as
  input to its analysis.

<Warning>
  The JSON Schema cannot compare two fields, so a schema-only check accepts a segment whose `end_s`
  is not after its `start_s`. Preflight and ingest reject it (`segment.end_s.invalid`). Check with
  [preflight](/mcap-spec/validation#preflight).
</Warning>


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