Datasets_CreateDataset
const url = 'https://dev-api.qualiastudios.dev/v1/accounts/example/datasets';const options = { method: 'POST', headers: {'X-API-Key': '<X-API-Key>', 'Content-Type': 'application/json'}, body: '{"name":"example","displayName":"example","description":"example","kind":"KIND_UNSPECIFIED","labels":{"task":"example","robot":"example","operator":"example","method":"example","scene":"example","methods":["example"],"environment":"ENVIRONMENT_UNSPECIFIED","origin":"ORIGIN_UNSPECIFIED","teleopInput":"TELEOP_INPUT_UNSPECIFIED"},"sourceRobot":"example","targetRobot":"example","etag":"example","curatedFrom":"example","reachSettings":{"solver":"SOLVER_UNSPECIFIED","baseM":[1],"homeHeadingRad":1},"linkedTask":"example","tags":["example"]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://dev-api.qualiastudios.dev/v1/accounts/example/datasets \ --header 'Content-Type: application/json' \ --header 'X-API-Key: <X-API-Key>' \ --data '{ "name": "example", "displayName": "example", "description": "example", "kind": "KIND_UNSPECIFIED", "labels": { "task": "example", "robot": "example", "operator": "example", "method": "example", "scene": "example", "methods": [ "example" ], "environment": "ENVIRONMENT_UNSPECIFIED", "origin": "ORIGIN_UNSPECIFIED", "teleopInput": "TELEOP_INPUT_UNSPECIFIED" }, "sourceRobot": "example", "targetRobot": "example", "etag": "example", "curatedFrom": "example", "reachSettings": { "solver": "SOLVER_UNSPECIFIED", "baseM": [ 1 ], "homeHeadingRad": 1 }, "linkedTask": "example", "tags": [ "example" ] }'Creates a mixture. Its sources are added with Mixtures.BatchCreateSources (several at once, resolved together) or Mixtures.CreateSource; a mixture with no sources reads nothing.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”The account id.
Query Parameters
Section titled “Query Parameters ”Idempotency key (AIP-155): a retry with the same id within 24 hours returns the first call’s result instead of creating a second one.
Request Body required
Section titled “Request Body required ”A dataset is an upload (one recording session, as it arrived), a mixture (kept up to date from other datasets) or a merge of uploads (several uploads reviewed, versioned and trained as one). All three have the same page and the same API: episodes, issues and versions nest under any of them.
Served by qds-api.
object
Accounts/{account}/datasets/{dataset}
Human name shown in the dashboard.
Free text about the dataset.
Upload, mixture or merged. Only MIXTURE can be created through CreateDataset; uploads arrive through the upload path and MERGED is made by MergeDatasets.
Where the dataset stands (the UI calls it status).
How far along the current status is, 0 to 1 (share of the upload landed while UPLOADING, share of episodes no longer waiting while REVIEWING).
Session labels. Editable on an upload and on a merged dataset, derived (the commonest value over what it reads, a merged dataset’s own for the uploads it holds) on a mixture. A merged dataset’s are its own: chosen when the merge makes it (an answer, else its uploads’ commonest), its collection tags seeded from its initial uploads and preserved on append. Every collection edit, including a compatibility method/axis edit, stays on the owner. Recording annotations on the uploads’ takes stay separate.
object
Task label, e.g. “restock shelf”. Empty means unlabeled.
The robot label as recorded (a robot type key such as “openarm”), or “umi-handheld” for handheld capture. Not the fleet robot; see source_robot.
Operator label (a name or a hashed id).
Legacy single-method value: teleop, vr, handheld, egocentric, policy_rollout, umi, policy-rollout, sim, or empty. An upload’s starts as its episodes’ commonest.
Scene label, e.g. “shelf”.
Compatibility projection of Dataset.tags containing only the original six collection-method names, including saved axis aliases. Legacy method edits declare their human methods and positive axis aliases; existing saved independent axes and free names remain authoritative. Use typed axis paths or human_methods_only for independent edits.
Saved environment authority for derived real-world/sim tags. An axis edit changes only its pair; missing evidence does not prove real-world.
Saved origin authority for derived human/policy-rollout tags. Missing policy metadata never proves human-collected origin.
Saved controller authority for derived vr/gello tags. A controller does not establish teleoperation, and absence establishes no controller.
Accounts/{account}/robots/{robot}: the fleet robot the episodes were recorded on. Empty for handheld data or when unmapped. A robot, not a gripper design (a Robot of kind GRIPPER); it is not looked up when set. A merged dataset’s uploads share one, chosen at the merge; changing it changes it on every upload it holds.
Accounts/{account}/robots/{robot}: the robot the episodes are played on (QUA-2340). Set by default only on handheld uploads (method “handheld”), to the account’s oldest robot (never a gripper design); empty otherwise until set. Changing it asks for no reach check; it closes the dataset’s open out_of_reach issues, which were about the previous robot. Name a robot, not a gripper design (a Robot of kind GRIPPER): it is not looked up when set. Changing a merged dataset’s changes it on every upload it holds; an upload merged away cannot be changed on its own.
Episode, time and standing counts.
object
Episodes in the dataset (for a mixture: in its resolved head).
Frames across every episode.
Recorded time across every episode, in seconds.
Episodes standing KEPT here.
Episodes standing UNREVIEWED here.
Episodes standing REJECTED here (validation rejects included).
Of those, rejected by ingest validation.
Open blocking issues in this dataset’s scope, on the dataset itself or on episodes not rejected here.
Upload only, and set by GetDataset alone (it sums every file): the bytes of every file in its repository as published.
Upload only, and set by GetDataset alone: how many files those are.
Episodes a person ruled on here (QUA-4024): those a person’s keep or
reject in this dataset’s scope (a merged dataset’s: its uploads’ too)
stands on, a split take’s on each of its pieces without a ruling of
their own. An episode kept because nothing blocks it, and a validation
reject, are not counted. At most kept + rejected.
What stable and head resolve to.
object
The newest tag; unset when there is none yet.
object
The version tag it stands at, e.g. “1.0”; empty for head.
Content digest of the episode set, “b3:
Episodes in that set.
What the dataset yields now; always set.
object
The version tag it stands at, e.g. “1.0”; empty for head.
Content digest of the episode set, “b3:
Episodes in that set.
Head against the newest tag.
object
The tag measured from; empty when the dataset has no tag yet.
Episodes head yields that the tag does not.
Episodes the tag pins that head no longer yields.
Episodes in both whose pinned revision differs from head’s (an edit: trim, subtasks, tags). Training reads exact revisions, so these count.
Robot interface and cameras.
object
Canonical robot-interface hash b3:<hex> (ADR 0008); empty until derived.
Canonical state channel keys, e.g. “left.joint.1”, “right.ee.x”.
Canonical action channel keys.
Camera keys, e.g. “context”, “wrist_left”.
Frames per second of the data rows.
Mixture only: the episodes it reads come from more than one interface.
Each state channel in vector order. A converted handheld upload’s are
the pair-frame channels its takes are sampled in. A merged dataset’s are
its uploads’ (one entry per native channel, with sides where they
resolve it differently), on GetDataset only. Empty on a mixture, whose
uploads each place their channels their own way.
One state or action channel of an upload: where it sits in the recording and the canonical key it resolves to.
object
Its position in the state or action vector: the n of the “state[n]” and “action[n]” keys Episodes.SampleEpisodeSeries returns.
The name the recording gives it, e.g. “left_joint_1.pos”. (— api-linter: core::0122::name-suffix=disabled aip.dev/not-precedent: a recorded channel label, not a resource name; the catalog and the mapping lens both call it this. —)
The canonical key it resolves to, e.g. “left.joint_1.pos”;
“unmapped:
“rad”, “m” or “norm”; empty when not known.
True when a person’s channel mapping resolved it, not the name.
Merged only: each key the uploads it holds resolve this channel to,
with the uploads that give it, when they do not agree (a merged
dataset made before its merge asked, or while a remap settles).
Empty when every upload gives canonical_key.
One canonical key some of a merged dataset’s uploads give a channel.
object
The canonical key, e.g. “gripper.pos”.
Accounts/{account}/datasets/{dataset}: the uploads that give it.
Each action channel in vector order, as native_state_channels.
One state or action channel of an upload: where it sits in the recording and the canonical key it resolves to.
object
Its position in the state or action vector: the n of the “state[n]” and “action[n]” keys Episodes.SampleEpisodeSeries returns.
The name the recording gives it, e.g. “left_joint_1.pos”. (— api-linter: core::0122::name-suffix=disabled aip.dev/not-precedent: a recorded channel label, not a resource name; the catalog and the mapping lens both call it this. —)
The canonical key it resolves to, e.g. “left.joint_1.pos”;
“unmapped:
“rad”, “m” or “norm”; empty when not known.
True when a person’s channel mapping resolved it, not the name.
Merged only: each key the uploads it holds resolve this channel to,
with the uploads that give it, when they do not agree (a merged
dataset made before its merge asked, or while a remap settles).
Empty when every upload gives canonical_key.
One canonical key some of a merged dataset’s uploads give a channel.
object
The canonical key, e.g. “gripper.pos”.
Accounts/{account}/datasets/{dataset}: the uploads that give it.
Lineage (QUA-1796). Mixture: the uploads it reads at head, once each, an upload a merge took named by its merged dataset (once for all it holds, QUA-3511). Merged: the uploads it holds, in the order they were merged. Upload: empty.
The mixtures that read this dataset directly: by name, or (for an upload or a merged dataset) through a label source it matches.
A signed midpoint poster from the first episode with one, in source and member order, searching the first 128 members per visible source. Empty when no poster can be delivered within that search.
Upload only: the repository it was published into (the git-native view).
Upload only: persisted ingest format.
Upload only: how the ingest ended.
Upload only: ”
Who created it (the uploader, or the person who made the mixture).
object
What kind of actor it is.
The person’s user id when kind is PERSON; empty otherwise.
The person’s display name at the time, for rendering without a lookup.
The rule code, or the model id (e.g. “gemini-robotics-er”), when not a person.
The run a model or rule finding came from, when it has one.
The API key’s id when a person acted through one; empty for a session. Never the key itself.
Signed identity evidence recorded with the change, kept apart from the principal above. Unset on older records and wherever none was signed.
object
How the principal authenticated.
The user id of a person verified as starting the work: the person of a session, or the person a trusted service’s signed job record names. Empty when nobody was verified.
The initiator’s display name at the time, never their email.
The user id of the key’s creator at the time. Not who used the key.
Who owned the key at the time.
The owning space’s id (a workspace or the organization) when
credential_owner is SPACE.
When the dataset was first published or created.
When anything about it last changed (a ruling, an issue, a source, a tag).
Sent back on UpdateDataset and DeleteDataset to guard against lost updates; a stale etag fails with ABORTED.
The name a training run cites (Version.reference = ”
Upload only, and only a handheld (UMI) upload whose state ingest placed in the pair frame: where its poses are. ROOT or TCP; unspecified for any other dataset. Read from the published repository (meta/ingest.toml and calibration.json), so it is filled by GetDataset alone: unset on ListDatasets, CreateDataset and UpdateDataset. (— api-linter: core::0140::prepositions=disabled aip.dev/not-precedent: “Poses at” is the product’s own name for where a handheld upload’s poses are. —)
Upload only: the calibration the TCP poses were resolved with, as it was when they were. Set when poses_at is TCP, and then only by GetDataset. Compare it with a rig’s calibration to tell whether that rig’s calibration has been replaced since.
object
The uploaded file’s name, e.g. “tcp_calibration.json”.
When the calibration was made, “YYYY-MM-DD”: the leading date of the
file’s calibrated or else its derived text. Empty when the file gives
none.
Both hands, left then right.
One hand’s transform.
object
Which hand.
The TCP’s pose in the tracker’s frame: xyz in metres and rpy in radians (URDF convention, extrinsic XYZ), the file’s rotation matrix converted. A rotation whose pitch is within a hair of +-90 degrees has no unique roll and yaw; it is stored with roll 0. (— api-linter: core::0140::prepositions=disabled aip.dev/not-precedent: a transform is named by its direction, as the calibration file’s own controller_to_tcp is. —)
object
X, y, z in metres.
Roll, pitch, yaw in radians.
The same TCP in the frame of the gripper design’s ee_link for this
hand, in the form of tracker_to_tcp (so the same pitch limit). Display
only. Set with ee_link or not at all, and only when it composes with
the file’s controller_to_ee to the file’s controller_to_tcp, which is
what makes the TCP drawn the TCP used.
(— api-linter: core::0140::prepositions=disabled
aip.dev/not-precedent: a transform is named by its direction, as
the calibration file’s own ee_to_tcp is. —)
object
X, y, z in metres.
Roll, pitch, yaw in radians.
The link of the rig’s gripper design that Hand.ee_to_tcp is a pose in,
with {side} for “left” or “right” (the gripper joint’s convention in
RobotModel.Gripper), e.g. “openarm_{side}_ee_base_link”. Read from the
file’s own description of its end-effector frame. Empty when the file
names none, lacks the end-effector poses, or they disagree with its
controller_to_tcp (then no ee_to_tcp is set either). Display only.
ee_to_tcp is drawn in this link’s own frame, which must be the plain
end-effector frame the file means. An export whose link sits elsewhere
draws the TCP off by the difference: an OpenArm exported with the xacro
default collapse_internal_empty_links puts openarm_
Upload only, with poses_at: the key of the rig ingest recognised the
upload as recorded on (“umi-handheld”), which is the rig whose
calibration a ResolvePoses takes. Ingest decides it from the recorder’s
robot_type, from the upload’s meta/ingest.toml [rig], or from the state
channel names, so it can name a rig when Episode.rig (for a LeRobot
upload only meta/info.json’s robot_type) is empty or something else.
Filled by GetDataset alone, like poses_at.
Upload only: true when GetDataset could not read the upload’s repository for poses_at, poses_calibration and poses_rig, so they are unknown here and unspecified does not mean there are none. The rest of the dataset is answered as usual; read it again for the poses.
Upload only: the merged dataset that holds it, once it was merged into
one (MergeDatasets). Empty otherwise, including after member removal.
While held, it leaves the unfiltered ListDatasets; its reads
keep answering, by name and by slug (its versions, which keep resolving
as <slug>:<tag>, its takes, issues, ingest report and re-ingests), and
every write that names it, or an episode, issue or version under it, is
FAILED_PRECONDITION naming the merged dataset, through which it is
written.
Mixture only: the upload version it curates from (QUA-3539), as accounts/{account}/datasets/{dataset}/versions/{tag}; set on create (CreateDataset) and never changed. Such a branch reads that upload as the version froze it, through one source pinned there: the upload’s rulings and blocking issues since reach neither it nor what reads it, its episodes read at the revisions the version pinned, its own keeps and rejects curate it, and edits are made in the upload. Empty for any other dataset. (— api-linter: core::0140::prepositions=disabled aip.dev/not-precedent: “curated from” is the product’s name for the version a branch reads. —)
How the dataset’s reach check is walked, as the dataset stores it: what is unset follows the target robot’s model (see Checks.GetReachStatus for what a RunCheck would use now). Saving it starts nothing.
object
The IK solver a dataset asks for, PYROKI or DLS. Unset (SOLVER_UNSPECIFIED) follows the target robot’s model, which may be MINK (a run’s resolved settings then say MINK; a request naming it is refused).
Where the takes’ start sits from the relaxed grippers’ midpoint, metres
in the robot’s base frame (x forward, y left, z up): empty or exactly
three numbers, each finite and within 5 m either way. Empty follows the
target robot model’s reach_base, else 0, 0, 0. Stored to 0.1 mm and
applied to both hand paths as one rigid translation from the robot’s home
hand midpoint.
Rotate both paired paths around world up before placing their first-row midpoint at the shared home reference. Radians; finite and within +/- pi. The robot base remains at world (0, 0, 0).
Where the source episode’s hand poses were recorded. Set by qds-api on reads; clients do not set it. TCP runs consume already-resolved TCP channels and never apply calibration again.
Digest of the TCP calibration already applied to the published upload, empty for root poses. Set by qds-api on reads.
Accounts/{account}/tasks/{task}: the Task an upload is recorded against (QUA-3116), or empty when unlinked. A link, not a label: labels.task stays the text. Set on an upload (a task of its account, NOT_FOUND otherwise), or on a merged dataset, whose own it is (chosen when the merge makes it: an answer, else its uploads’ commonest; its uploads keep theirs); a mixture shows the commonest link of the uploads it reads (a merged dataset’s own for the uploads it holds). Linking by label (LinkTaskLabels, and publishing a task) links an upload or a merged dataset by its own labels.task, never an upload a merge took. Deleting the task unlinks it. A mixture source can follow every upload and merged dataset linked to one task (Source.linked_task). Every take of an upload or a merged dataset with no link of its own reads the dataset’s (QUA-3413, Episode.linked_task_inherited): a merged dataset’s takes read its own, not their uploads’ (QUA-3511), so setting it links them all at once; UpdateDatasetRequest.relink_episodes moves the takes linked to the old one as well.
Merged dataset only: member interfaces ready to freeze as one, and the uploads still awaiting or differing from the first member’s interface.
object
Number of merged members whose derived interfaces are settled.
Total number of uploads in the merged dataset.
Upload resource names whose interfaces are not settled yet.
The project that owns the dataset, empty when it is in the account’s default workspace. Gateway clients select it with X-Qualia-Workspace.
No longer set (QUA-3511): a merge is final and a merged dataset is not corrected through its uploads. It was GetDataset’s merged membership for a member settings operation.
object
The merged dataset whose membership was confirmed.
Every upload it held, in merge order, including the selected upload.
Opaque merge/undo epoch from GetDataset; never recapture it on retry.
The dataset’s editable etag; a member edit sends the selected upload’s.
The selected upload’s exact paired head. Empty on the merged dataset’s context, which is used only to fence global label edits.
No longer set (QUA-3511): a merged dataset’s poses are not resolved through its uploads.
No longer set (QUA-3511): a merged dataset’s uploads were settled at the merge (one contract, one pose frame); interface_settlement is its view of an interface still re-deriving.
object
Number of merged members whose derived interfaces are settled.
Total number of uploads in the merged dataset.
Upload resource names whose interfaces are not settled yet.
No longer set (QUA-3511), with settings_settlement.
GetDataset only: one per Task, by display name.
The Tasks this dataset’s episodes are references of (QUA-3412): a reference names its episode where it was recorded, or the merged dataset that upload went into (QUA-3511), so a mixture has none. Deleting the dataset removes those references (the Tasks stay), so DeleteDataset refuses until it is sent with force.
object
Accounts/{account}/tasks/{task}
The Task’s display name.
How many of the dataset’s episodes it references.
GetDataset only: how many distinct episodes those Tasks reference (an episode two Tasks reference counts once).
This dataset’s tags: up to 64 nonblank strings of at most 256 bytes. Recognized collection names are teleop, vr, umi, egocentric, policy-rollout, sim, real-world, human and gello; they are ordered first in that order, followed by free tags in lexical order. Environment, origin, method and controller derive from saved metadata. The tags mask may echo unchanged classifications and edit custom strings only; use typed metadata masks for classification changes or Unknown. A merged dataset owns its metadata, which is never written to its uploads or replaced when uploads are appended. A mixture reads the tags of its sources. Distinct from episode curation and version tags.
GetDataset only, merged datasets: each upload’s progress toward its own recognized rig’s CURRENT capture calibration. Independent of playback robot selection. A failed read is unknown, never a completed preparation.
object
Opaque ordered-membership epoch. Send it back on an explicit move or removal; a changed membership is ABORTED and must be confirmed again.
Number already at their current capture calibration.
Number of uploads in the current membership.
Preparation state for each upload, in membership order.
One upload’s current state. Names and reasons are suitable for the merged dataset’s pre-check; no source data or historical rulings are removed.
object
The source upload resource.
The source upload’s display name.
The upload’s current preparation state.
Human-readable explanation when applicable.
UUID polled at this upload’s reingests/{operation_id} resource.
Recording rig, never an editable collection tag or playback robot.
The capture gripper supplying the calibration.
The capture calibration’s version.
Preparation is complete and its publication is pending; it cannot be cancelled.
False when none of these recordings has handheld poses to prepare.
Responses
Section titled “ Responses ”OK
A dataset is an upload (one recording session, as it arrived), a mixture (kept up to date from other datasets) or a merge of uploads (several uploads reviewed, versioned and trained as one). All three have the same page and the same API: episodes, issues and versions nest under any of them.
Served by qds-api.
object
Accounts/{account}/datasets/{dataset}
Human name shown in the dashboard.
Free text about the dataset.
Upload, mixture or merged. Only MIXTURE can be created through CreateDataset; uploads arrive through the upload path and MERGED is made by MergeDatasets.
Where the dataset stands (the UI calls it status).
How far along the current status is, 0 to 1 (share of the upload landed while UPLOADING, share of episodes no longer waiting while REVIEWING).
Session labels. Editable on an upload and on a merged dataset, derived (the commonest value over what it reads, a merged dataset’s own for the uploads it holds) on a mixture. A merged dataset’s are its own: chosen when the merge makes it (an answer, else its uploads’ commonest), its collection tags seeded from its initial uploads and preserved on append. Every collection edit, including a compatibility method/axis edit, stays on the owner. Recording annotations on the uploads’ takes stay separate.
object
Task label, e.g. “restock shelf”. Empty means unlabeled.
The robot label as recorded (a robot type key such as “openarm”), or “umi-handheld” for handheld capture. Not the fleet robot; see source_robot.
Operator label (a name or a hashed id).
Legacy single-method value: teleop, vr, handheld, egocentric, policy_rollout, umi, policy-rollout, sim, or empty. An upload’s starts as its episodes’ commonest.
Scene label, e.g. “shelf”.
Compatibility projection of Dataset.tags containing only the original six collection-method names, including saved axis aliases. Legacy method edits declare their human methods and positive axis aliases; existing saved independent axes and free names remain authoritative. Use typed axis paths or human_methods_only for independent edits.
Saved environment authority for derived real-world/sim tags. An axis edit changes only its pair; missing evidence does not prove real-world.
Saved origin authority for derived human/policy-rollout tags. Missing policy metadata never proves human-collected origin.
Saved controller authority for derived vr/gello tags. A controller does not establish teleoperation, and absence establishes no controller.
Accounts/{account}/robots/{robot}: the fleet robot the episodes were recorded on. Empty for handheld data or when unmapped. A robot, not a gripper design (a Robot of kind GRIPPER); it is not looked up when set. A merged dataset’s uploads share one, chosen at the merge; changing it changes it on every upload it holds.
Accounts/{account}/robots/{robot}: the robot the episodes are played on (QUA-2340). Set by default only on handheld uploads (method “handheld”), to the account’s oldest robot (never a gripper design); empty otherwise until set. Changing it asks for no reach check; it closes the dataset’s open out_of_reach issues, which were about the previous robot. Name a robot, not a gripper design (a Robot of kind GRIPPER): it is not looked up when set. Changing a merged dataset’s changes it on every upload it holds; an upload merged away cannot be changed on its own.
Episode, time and standing counts.
object
Episodes in the dataset (for a mixture: in its resolved head).
Frames across every episode.
Recorded time across every episode, in seconds.
Episodes standing KEPT here.
Episodes standing UNREVIEWED here.
Episodes standing REJECTED here (validation rejects included).
Of those, rejected by ingest validation.
Open blocking issues in this dataset’s scope, on the dataset itself or on episodes not rejected here.
Upload only, and set by GetDataset alone (it sums every file): the bytes of every file in its repository as published.
Upload only, and set by GetDataset alone: how many files those are.
Episodes a person ruled on here (QUA-4024): those a person’s keep or
reject in this dataset’s scope (a merged dataset’s: its uploads’ too)
stands on, a split take’s on each of its pieces without a ruling of
their own. An episode kept because nothing blocks it, and a validation
reject, are not counted. At most kept + rejected.
What stable and head resolve to.
object
The newest tag; unset when there is none yet.
object
The version tag it stands at, e.g. “1.0”; empty for head.
Content digest of the episode set, “b3:
Episodes in that set.
What the dataset yields now; always set.
object
The version tag it stands at, e.g. “1.0”; empty for head.
Content digest of the episode set, “b3:
Episodes in that set.
Head against the newest tag.
object
The tag measured from; empty when the dataset has no tag yet.
Episodes head yields that the tag does not.
Episodes the tag pins that head no longer yields.
Episodes in both whose pinned revision differs from head’s (an edit: trim, subtasks, tags). Training reads exact revisions, so these count.
Robot interface and cameras.
object
Canonical robot-interface hash b3:<hex> (ADR 0008); empty until derived.
Canonical state channel keys, e.g. “left.joint.1”, “right.ee.x”.
Canonical action channel keys.
Camera keys, e.g. “context”, “wrist_left”.
Frames per second of the data rows.
Mixture only: the episodes it reads come from more than one interface.
Each state channel in vector order. A converted handheld upload’s are
the pair-frame channels its takes are sampled in. A merged dataset’s are
its uploads’ (one entry per native channel, with sides where they
resolve it differently), on GetDataset only. Empty on a mixture, whose
uploads each place their channels their own way.
One state or action channel of an upload: where it sits in the recording and the canonical key it resolves to.
object
Its position in the state or action vector: the n of the “state[n]” and “action[n]” keys Episodes.SampleEpisodeSeries returns.
The name the recording gives it, e.g. “left_joint_1.pos”. (— api-linter: core::0122::name-suffix=disabled aip.dev/not-precedent: a recorded channel label, not a resource name; the catalog and the mapping lens both call it this. —)
The canonical key it resolves to, e.g. “left.joint_1.pos”;
“unmapped:
“rad”, “m” or “norm”; empty when not known.
True when a person’s channel mapping resolved it, not the name.
Merged only: each key the uploads it holds resolve this channel to,
with the uploads that give it, when they do not agree (a merged
dataset made before its merge asked, or while a remap settles).
Empty when every upload gives canonical_key.
One canonical key some of a merged dataset’s uploads give a channel.
object
The canonical key, e.g. “gripper.pos”.
Accounts/{account}/datasets/{dataset}: the uploads that give it.
Each action channel in vector order, as native_state_channels.
One state or action channel of an upload: where it sits in the recording and the canonical key it resolves to.
object
Its position in the state or action vector: the n of the “state[n]” and “action[n]” keys Episodes.SampleEpisodeSeries returns.
The name the recording gives it, e.g. “left_joint_1.pos”. (— api-linter: core::0122::name-suffix=disabled aip.dev/not-precedent: a recorded channel label, not a resource name; the catalog and the mapping lens both call it this. —)
The canonical key it resolves to, e.g. “left.joint_1.pos”;
“unmapped:
“rad”, “m” or “norm”; empty when not known.
True when a person’s channel mapping resolved it, not the name.
Merged only: each key the uploads it holds resolve this channel to,
with the uploads that give it, when they do not agree (a merged
dataset made before its merge asked, or while a remap settles).
Empty when every upload gives canonical_key.
One canonical key some of a merged dataset’s uploads give a channel.
object
The canonical key, e.g. “gripper.pos”.
Accounts/{account}/datasets/{dataset}: the uploads that give it.
Lineage (QUA-1796). Mixture: the uploads it reads at head, once each, an upload a merge took named by its merged dataset (once for all it holds, QUA-3511). Merged: the uploads it holds, in the order they were merged. Upload: empty.
The mixtures that read this dataset directly: by name, or (for an upload or a merged dataset) through a label source it matches.
A signed midpoint poster from the first episode with one, in source and member order, searching the first 128 members per visible source. Empty when no poster can be delivered within that search.
Upload only: the repository it was published into (the git-native view).
Upload only: persisted ingest format.
Upload only: how the ingest ended.
Upload only: ”
Who created it (the uploader, or the person who made the mixture).
object
What kind of actor it is.
The person’s user id when kind is PERSON; empty otherwise.
The person’s display name at the time, for rendering without a lookup.
The rule code, or the model id (e.g. “gemini-robotics-er”), when not a person.
The run a model or rule finding came from, when it has one.
The API key’s id when a person acted through one; empty for a session. Never the key itself.
Signed identity evidence recorded with the change, kept apart from the principal above. Unset on older records and wherever none was signed.
object
How the principal authenticated.
The user id of a person verified as starting the work: the person of a session, or the person a trusted service’s signed job record names. Empty when nobody was verified.
The initiator’s display name at the time, never their email.
The user id of the key’s creator at the time. Not who used the key.
Who owned the key at the time.
The owning space’s id (a workspace or the organization) when
credential_owner is SPACE.
When the dataset was first published or created.
When anything about it last changed (a ruling, an issue, a source, a tag).
Sent back on UpdateDataset and DeleteDataset to guard against lost updates; a stale etag fails with ABORTED.
The name a training run cites (Version.reference = ”
Upload only, and only a handheld (UMI) upload whose state ingest placed in the pair frame: where its poses are. ROOT or TCP; unspecified for any other dataset. Read from the published repository (meta/ingest.toml and calibration.json), so it is filled by GetDataset alone: unset on ListDatasets, CreateDataset and UpdateDataset. (— api-linter: core::0140::prepositions=disabled aip.dev/not-precedent: “Poses at” is the product’s own name for where a handheld upload’s poses are. —)
Upload only: the calibration the TCP poses were resolved with, as it was when they were. Set when poses_at is TCP, and then only by GetDataset. Compare it with a rig’s calibration to tell whether that rig’s calibration has been replaced since.
object
The uploaded file’s name, e.g. “tcp_calibration.json”.
When the calibration was made, “YYYY-MM-DD”: the leading date of the
file’s calibrated or else its derived text. Empty when the file gives
none.
Both hands, left then right.
One hand’s transform.
object
Which hand.
The TCP’s pose in the tracker’s frame: xyz in metres and rpy in radians (URDF convention, extrinsic XYZ), the file’s rotation matrix converted. A rotation whose pitch is within a hair of +-90 degrees has no unique roll and yaw; it is stored with roll 0. (— api-linter: core::0140::prepositions=disabled aip.dev/not-precedent: a transform is named by its direction, as the calibration file’s own controller_to_tcp is. —)
object
X, y, z in metres.
Roll, pitch, yaw in radians.
The same TCP in the frame of the gripper design’s ee_link for this
hand, in the form of tracker_to_tcp (so the same pitch limit). Display
only. Set with ee_link or not at all, and only when it composes with
the file’s controller_to_ee to the file’s controller_to_tcp, which is
what makes the TCP drawn the TCP used.
(— api-linter: core::0140::prepositions=disabled
aip.dev/not-precedent: a transform is named by its direction, as
the calibration file’s own ee_to_tcp is. —)
object
X, y, z in metres.
Roll, pitch, yaw in radians.
The link of the rig’s gripper design that Hand.ee_to_tcp is a pose in,
with {side} for “left” or “right” (the gripper joint’s convention in
RobotModel.Gripper), e.g. “openarm_{side}_ee_base_link”. Read from the
file’s own description of its end-effector frame. Empty when the file
names none, lacks the end-effector poses, or they disagree with its
controller_to_tcp (then no ee_to_tcp is set either). Display only.
ee_to_tcp is drawn in this link’s own frame, which must be the plain
end-effector frame the file means. An export whose link sits elsewhere
draws the TCP off by the difference: an OpenArm exported with the xacro
default collapse_internal_empty_links puts openarm_
Upload only, with poses_at: the key of the rig ingest recognised the
upload as recorded on (“umi-handheld”), which is the rig whose
calibration a ResolvePoses takes. Ingest decides it from the recorder’s
robot_type, from the upload’s meta/ingest.toml [rig], or from the state
channel names, so it can name a rig when Episode.rig (for a LeRobot
upload only meta/info.json’s robot_type) is empty or something else.
Filled by GetDataset alone, like poses_at.
Upload only: true when GetDataset could not read the upload’s repository for poses_at, poses_calibration and poses_rig, so they are unknown here and unspecified does not mean there are none. The rest of the dataset is answered as usual; read it again for the poses.
Upload only: the merged dataset that holds it, once it was merged into
one (MergeDatasets). Empty otherwise, including after member removal.
While held, it leaves the unfiltered ListDatasets; its reads
keep answering, by name and by slug (its versions, which keep resolving
as <slug>:<tag>, its takes, issues, ingest report and re-ingests), and
every write that names it, or an episode, issue or version under it, is
FAILED_PRECONDITION naming the merged dataset, through which it is
written.
Mixture only: the upload version it curates from (QUA-3539), as accounts/{account}/datasets/{dataset}/versions/{tag}; set on create (CreateDataset) and never changed. Such a branch reads that upload as the version froze it, through one source pinned there: the upload’s rulings and blocking issues since reach neither it nor what reads it, its episodes read at the revisions the version pinned, its own keeps and rejects curate it, and edits are made in the upload. Empty for any other dataset. (— api-linter: core::0140::prepositions=disabled aip.dev/not-precedent: “curated from” is the product’s name for the version a branch reads. —)
How the dataset’s reach check is walked, as the dataset stores it: what is unset follows the target robot’s model (see Checks.GetReachStatus for what a RunCheck would use now). Saving it starts nothing.
object
The IK solver a dataset asks for, PYROKI or DLS. Unset (SOLVER_UNSPECIFIED) follows the target robot’s model, which may be MINK (a run’s resolved settings then say MINK; a request naming it is refused).
Where the takes’ start sits from the relaxed grippers’ midpoint, metres
in the robot’s base frame (x forward, y left, z up): empty or exactly
three numbers, each finite and within 5 m either way. Empty follows the
target robot model’s reach_base, else 0, 0, 0. Stored to 0.1 mm and
applied to both hand paths as one rigid translation from the robot’s home
hand midpoint.
Rotate both paired paths around world up before placing their first-row midpoint at the shared home reference. Radians; finite and within +/- pi. The robot base remains at world (0, 0, 0).
Where the source episode’s hand poses were recorded. Set by qds-api on reads; clients do not set it. TCP runs consume already-resolved TCP channels and never apply calibration again.
Digest of the TCP calibration already applied to the published upload, empty for root poses. Set by qds-api on reads.
Accounts/{account}/tasks/{task}: the Task an upload is recorded against (QUA-3116), or empty when unlinked. A link, not a label: labels.task stays the text. Set on an upload (a task of its account, NOT_FOUND otherwise), or on a merged dataset, whose own it is (chosen when the merge makes it: an answer, else its uploads’ commonest; its uploads keep theirs); a mixture shows the commonest link of the uploads it reads (a merged dataset’s own for the uploads it holds). Linking by label (LinkTaskLabels, and publishing a task) links an upload or a merged dataset by its own labels.task, never an upload a merge took. Deleting the task unlinks it. A mixture source can follow every upload and merged dataset linked to one task (Source.linked_task). Every take of an upload or a merged dataset with no link of its own reads the dataset’s (QUA-3413, Episode.linked_task_inherited): a merged dataset’s takes read its own, not their uploads’ (QUA-3511), so setting it links them all at once; UpdateDatasetRequest.relink_episodes moves the takes linked to the old one as well.
Merged dataset only: member interfaces ready to freeze as one, and the uploads still awaiting or differing from the first member’s interface.
object
Number of merged members whose derived interfaces are settled.
Total number of uploads in the merged dataset.
Upload resource names whose interfaces are not settled yet.
The project that owns the dataset, empty when it is in the account’s default workspace. Gateway clients select it with X-Qualia-Workspace.
No longer set (QUA-3511): a merge is final and a merged dataset is not corrected through its uploads. It was GetDataset’s merged membership for a member settings operation.
object
The merged dataset whose membership was confirmed.
Every upload it held, in merge order, including the selected upload.
Opaque merge/undo epoch from GetDataset; never recapture it on retry.
The dataset’s editable etag; a member edit sends the selected upload’s.
The selected upload’s exact paired head. Empty on the merged dataset’s context, which is used only to fence global label edits.
No longer set (QUA-3511): a merged dataset’s poses are not resolved through its uploads.
No longer set (QUA-3511): a merged dataset’s uploads were settled at the merge (one contract, one pose frame); interface_settlement is its view of an interface still re-deriving.
object
Number of merged members whose derived interfaces are settled.
Total number of uploads in the merged dataset.
Upload resource names whose interfaces are not settled yet.
No longer set (QUA-3511), with settings_settlement.
GetDataset only: one per Task, by display name.
The Tasks this dataset’s episodes are references of (QUA-3412): a reference names its episode where it was recorded, or the merged dataset that upload went into (QUA-3511), so a mixture has none. Deleting the dataset removes those references (the Tasks stay), so DeleteDataset refuses until it is sent with force.
object
Accounts/{account}/tasks/{task}
The Task’s display name.
How many of the dataset’s episodes it references.
GetDataset only: how many distinct episodes those Tasks reference (an episode two Tasks reference counts once).
This dataset’s tags: up to 64 nonblank strings of at most 256 bytes. Recognized collection names are teleop, vr, umi, egocentric, policy-rollout, sim, real-world, human and gello; they are ordered first in that order, followed by free tags in lexical order. Environment, origin, method and controller derive from saved metadata. The tags mask may echo unchanged classifications and edit custom strings only; use typed metadata masks for classification changes or Unknown. A merged dataset owns its metadata, which is never written to its uploads or replaced when uploads are appended. A mixture reads the tags of its sources. Distinct from episode curation and version tags.
GetDataset only, merged datasets: each upload’s progress toward its own recognized rig’s CURRENT capture calibration. Independent of playback robot selection. A failed read is unknown, never a completed preparation.
object
Opaque ordered-membership epoch. Send it back on an explicit move or removal; a changed membership is ABORTED and must be confirmed again.
Number already at their current capture calibration.
Number of uploads in the current membership.
Preparation state for each upload, in membership order.
One upload’s current state. Names and reasons are suitable for the merged dataset’s pre-check; no source data or historical rulings are removed.
object
The source upload resource.
The source upload’s display name.
The upload’s current preparation state.
Human-readable explanation when applicable.
UUID polled at this upload’s reingests/{operation_id} resource.
Recording rig, never an editable collection tag or playback robot.
The capture gripper supplying the calibration.
The capture calibration’s version.
Preparation is complete and its publication is pending; it cannot be cancelled.
False when none of these recordings has handheld poses to prepare.
Example
{ "kind": "KIND_UNSPECIFIED", "state": "STATE_UNSPECIFIED", "labels": { "environment": "ENVIRONMENT_UNSPECIFIED", "origin": "ORIGIN_UNSPECIFIED", "teleopInput": "TELEOP_INPUT_UNSPECIFIED" }, "sourceFormat": "SOURCE_FORMAT_UNSPECIFIED", "verdict": "VERDICT_UNSPECIFIED", "creator": { "kind": "KIND_UNSPECIFIED", "attribution": { "authentication": "AUTHENTICATION_UNSPECIFIED", "credentialOwner": "CREDENTIAL_OWNER_UNSPECIFIED" } }, "posesAt": "POSES_AT_UNSPECIFIED", "posesCalibration": { "hands": [ { "side": "SIDE_UNSPECIFIED" } ] }, "reachSettings": { "solver": "SOLVER_UNSPECIFIED", "poseSource": "POSES_AT_UNSPECIFIED" }, "posePreparation": { "members": [ { "state": "STATE_UNSPECIFIED" } ] }}default
Section titled “default ”Default error response
The Status type defines a logical error model that is suitable for different programming environments, including REST APIs and RPC APIs. It is used by gRPC. Each Status message contains three pieces of data: error code, error message, and error details. You can find out more about this error model and how to work with it in the API Design Guide.
object
The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].
A developer-facing error message, which should be in English. Any user-facing error message should be localized and sent in the [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client.
A list of messages that carry the error details. There is a common set of message types for APIs to use.
Contains an arbitrary serialized message along with a @type that describes the type of the serialized message.
object
The type of the serialized message.
Example generated
{ "code": 1, "message": "example", "details": [ { "@type": "example" } ]}