Skip to main content
Every sequence carries two separate kinds of metadata:
  • Technical validity. Is the recording usable? Avala reports it from acceptance criteria and quality targets. See Technical validity.
  • Behavioral outcome. What did the person or the robot do, and did the task succeed? Avala stores it as the sequence’s outcome label.
A sequence can be technically valid and still show a failure. A failed sequence is often the most useful one. The two axes stay apart, so a filter for clean data never drops a useful failure, and a filter for success never hides a broken sensor.

The outcome label

Each sequence has at most one current outcome label. Every write records a new version. Earlier versions stay readable in the label history.

Example

This is the label of a human demonstration with a slip and a recovery, as GET .../sequences/<sequence-uid>/outcome/ returns it:
The values illustrate the shape of the label. They do not describe a real delivery.

Fields

All timestamps are seconds from the start of the sequence. mistake_type, recovery_type and failure_stage are free text. Use the tags from your program’s failure taxonomy so that sequences group cleanly.

Outcome values

Each subtask can carry its own outcome from the same list.

Autonomy level

Subtasks

Each subtask is {label, start_ts, end_ts, outcome}, with an optional reward. Leave reward out when you did not label one. Avala stores it only when you send it, so a missing reward is “not labeled” and a 0 is a reward of zero. Sending null is the same as leaving it out. reward does not change the ordering or nesting rules below. A label holds at most 256 subtasks. The list must be ordered by start_ts. Any two subtasks are either disjoint or one fully contains the other, such as a phase and its steps. Touching ends count as disjoint. A partial overlap is rejected. When two subtasks start at the same time, list the enclosing one first.

Hand actions

hand_actions holds two independent streams, left and right. Each item describes what one hand does over a time range.
  • Within one hand, items are ordered by start_ts and must not overlap. An item starts at or after the end of the previous one. Touching is fine.
  • The two hands overlap freely.
  • Each hand holds at most 3,600 items. That is one hour at one label per second.
  • left and right are the only keys. You can omit either one. An omitted hand is stored as an empty list.
  • An empty object or verb is stored as null. Every stored item has all six fields.

Sequence duration

When Avala knows the duration of the sequence, every subtask end_ts and every hand-action end_ts must be at most the duration plus 1 second. The extra second allows for labels written at one per second. Avala knows the duration when the sequence has exactly one extracted MCAP file with a recorded length. For other sequences the check is skipped.

Evaluation membership

evaluation_membership places the sequence in a split: Avala sets held_out_eval on the sequences of every evaluation cohort. Those sequences never appear in a training release. See Evaluation.

Leakage groups

Leakage groups stop near-duplicates from landing on both sides of a train and evaluation split. leakage_groups accepts these keys, each with a group ID of up to 255 characters: Any other key is rejected. Each key is optional. Avala builds evaluation cohorts so that no group value in a cohort appears in any training release. You can split your own data the same way: hold out by group, never by random sequence. Avala’s group IDs are pseudonymous, so you can group and split without learning who or where.

Source metadata

source_metadata records where an imported label came from, for example {"importer": "...", "run_id": "...", "task": "...", "log_path": "..."}.
  • It is a flat object with at most 20 keys.
  • Each key is 1 to 64 characters.
  • Each value is a string of up to 512 characters, a finite number or a boolean.
  • Nested objects, lists and null values are rejected.

How writes work

  • A write replaces the current label as a whole and records a new version. Any optional field you leave out is stored as unset. It is not copied from the previous version.
  • Writing needs edit access to the dataset. Reading needs the same access as reading the sequence, including public datasets.
  • confidence is rejected unless source is model.
  • Reading a sequence that has no label returns 404.

Technical validity

Technical validity is not part of the outcome label. Avala reports it from the acceptance engine and from quality targets, and it has no JSON schema of its own. Acceptance criteria. Every capture in a capture campaign gets a machine verdict: accept, quarantine or reject. The verdict comes from these criteria: Each criterion reports pass, fail, insufficient_evidence or skipped. A failed criterion records a reason code, such as acceptance_frame_rate_drop or hands_not_visible. A reviewer then confirms or overrides the verdict. The reason codes are listed in Accepted hour. Read acceptance with the MCP tools get_result_acceptance for one capture and get_campaign_acceptance_summary for a campaign. list_capture_submissions includes the machine acceptance summary of each capture. Quality targets. A project can set thresholds on quality metrics, such as acceptance rate, rejection rate and issue rate. Avala alerts when a metric crosses its threshold. Read them with the MCP tool list_quality_targets. Program checks that are not machine criteria, such as calibration, consent and timestamp sync, are reported as rejection reasons in the coverage report. See Accepted hour.

Read and write outcome labels

The REST endpoints live under https://api.avala.ai/api/v1: The dataset list accepts the filters outcome, evaluation_membership, source and autonomy_level. Each takes one value or a comma-separated list, and a sequence matches any value in the list. model_version matches one exact version. An unknown filter value returns 400. The sequence list, GET /datasets/{owner}/{slug}/sequences/, accepts outcome and evaluation_membership in the same form. It returns the sequences whose current label matches.

Write a label

The TypeScript SDK takes camelCase option names and sends the API’s snake_case fields. Keys inside sourceMetadata are sent as written. In the CLI, --hand-actions-file takes a JSON file with {"left": [...], "right": [...]}, and --leakage-group KEY=ID can be repeated.

Read labels

The dataset list returns up to 100 labels per page. Pass the cursor from the previous page to continue.

Read labels with the MCP server

The MCP server reads outcome labels. It does not write them.
  • get_sequence_outcome takes owner, slug and sequenceUid. It returns the current label.
  • list_sequence_outcomes takes owner and slug, plus the filters outcome, evaluationMembership, source, autonomyLevel and modelVersion, and limit and cursor.
Both tools return a short form by default. Pass detail: "full" to include subtasks, hand actions, the mistake and recovery tags, leakage groups, source metadata and the labeler. See Use Avala with AI to connect.

Export outcome labels with LeRobot

The LeRobot exporter can write each sequence’s current outcome label next to the dataset. One Avala sequence becomes one LeRobot episode.
The labels are written to meta/avala_sequence_outcomes.jsonl, one JSON object per line and one line per saved LeRobot episode. LeRobot’s own episode table has no place for this metadata, so it is a separate file. Each line has these keys: A sequence without a label gets a line with only episode_index, avala_sequence_uid and "outcome": null.

The failure-and-recovery lane

Recoverable failures are delivered as their own lane: sequences whose outcome is mistake_and_recovery or intervention. The subtasks and hand actions of each sequence mark where the failure and the recovery happen. The lane ships as a separate slice in the release. You can train on it, weight it or leave it out. You can also build the same set yourself with ?outcome=mistake_and_recovery,intervention. Unsafe sequences are not part of the lane.