Episodes_ListEpisodes
const url = 'https://dev-api.qualiastudios.dev/v1/accounts/example/datasets/example/episodes?view=EPISODE_VIEW_UNSPECIFIED';const options = {method: 'GET', headers: {'X-API-Key': '<X-API-Key>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://dev-api.qualiastudios.dev/v1/accounts/example/datasets/example/episodes?view=EPISODE_VIEW_UNSPECIFIED' \ --header 'X-API-Key: <X-API-Key>'Lists the episodes of a dataset in recording order (for a mixture: its
pool, source by source). parent may be accounts/a/datasets/- to read
across every dataset of the account (ExploreLake’s successor).
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”The account id.
The dataset id.
Query Parameters
Section titled “Query Parameters ”At most this many episodes; 0 means 100, the maximum is 1000.
From a previous response’s next_page_token.
AIP-160 filter; the field list is in docs/design/dataset-workflow-api.md
(“Episode filter”). e.g. state = UNREVIEWED AND open_issue_codes:"jerky",
methods:"umi", version = "1.0", metrics.duration_seconds < 20,
viewed = false, linked_task_inherited = false, draft = true
(takes with a draft, Episode.draft).
“index” (default: recording order, source by source in a mixture),
“record_time”, “metrics.
EPISODE_VIEW_ANALYSIS adds each episode’s Episode.analysis, its channels’ progress only: a channel’s curves are GetEpisode’s. It signs no posters (Episode.posters is empty): a reader of every take’s profile shows few posters, and reads those with GetEpisode (QUA-3486).
Read as this version froze it (QUA-3539): a tag, stable, v0 or a
digest prefix; empty or head reads the episode as it is now. The list
holds that version’s episodes, each with the fields, trim and subtasks of
the revision it pinned (task and tags as its snapshot froze them, also
for an episode never edited); standing, decision, issues and markers are
current. A version the dataset does not have is NOT_FOUND.
(— api-linter: core::0132::request-unknown-fields=disabled
aip.dev/not-precedent: a version is a frozen read of the same
collection, not a filter: its episodes carry the revisions it pinned. —)
Responses
Section titled “ Responses ”OK
Response for Episodes.ListEpisodes.
object
One page of episodes.
One take. An episode is recorded in exactly one upload, and can be read
through any dataset that contains it: the parent in its name is the scope
it is seen from. accounts/a/datasets/{upload}/episodes/{e} is the take as
its upload stands on it; accounts/a/datasets/{mixture}/episodes/{e} is the
same take as that mixture stands on it. The {episode} id is the same uuid
in both. Rulings (Keep, Reject, …) made through a mixture’s name belong to
that mixture (QUA-2242). Upstream wins: seen from a mixture, an episode its
upload (or a mixture in between) does not keep stands as it stands there,
read-only; only an upstream KEPT episode is the mixture’s to rule on.
A merged dataset (Datasets.MergeDatasets) holds its uploads’ episodes where
they were recorded: accounts/a/datasets/{merged}/episodes/{e} is the take
as its upload stands on it, the same state, decision, issues, notes, tags
and trim, and upload still names the upload it came from. A merge is
final (QUA-3511): the take is the merged dataset’s, and everything written
to it (a ruling, an issue, UpdateEpisodes, AssignTask, splits, suggestions)
is sent through the merged name and lands in the upload that holds it. The
upload’s own name for it still reads; a write by that name is
FAILED_PRECONDITION naming the merged dataset. The account-wide list
(datasets/-) names such a take under its merged dataset.
Served by qds-api.
object
Accounts/{account}/datasets/{dataset}/episodes/{episode}
Accounts/{account}/datasets/{dataset}: the upload it was recorded in.
The upload filter compares it with a dataset name, = and !=; a
merged dataset’s name matches the episodes of every upload it holds, as
one comparison (QUA-3511).
Its position in the upload, from 0.
Its place in the dataset it is read through, from 0: what it is numbered
by there. In a merged dataset, across its uploads, in the order they
were merged, each upload’s episodes in their own order, so no two share
a number (QUA-3328); everywhere else it is index.
Optional for older servers that do not yet report it; clients can
distinguish an absent position from the valid value zero.
The episode it was split from, when it is a child (QUA-2254).
Children it was split into.
Where a split child sits in its parent (QUA-3539), in seconds from the
start of the parent’s recording: what parent_episode traces it back
to. It is the child’s base window, the stretch the split gave it; a
later trim of the child narrows the child, not this window (QUA-3614).
Unset for an episode that was not split from another.
object
First second kept.
Last second kept.
The index of the episode it was split from, when it is a split child.
Where it stands in this scope. Derivation in docs/design/dataset-workflow-api.md.
The standing ruling in this scope; unset when nobody (and not validation) ruled.
object
Keep or reject.
Who ruled: a person, or VALIDATION for an ingest reject.
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.
Why, in the person’s words; for validation, the invalid reasons.
Accounts/{account}/datasets/{dataset}: the dataset the ruling was made in. Equals the upload for an upload ruling; a mixture for its own rejects.
True when seen from a mixture and the deciding ruling was made upstream: only that dataset can take it back.
Open blocking issues on it, in this scope.
Notes (non-blocking) on it, in this scope.
Codes of the open issues, for rail chips without a second call.
Codes of the open notes (issues that do not block a keep) that carry one (QUA-4024): a check’s findings, such as a graph check’s, and ingest’s non-blocking ones. A person’s note has no code and is not listed.
Whether the caller has opened it (QUA-2231). Per person: always false for an API key, which acts as itself, not as the person who made it.
Frames in the recording.
Frames per second of the data rows.
When it was recorded.
Camera keys it carries.
First and last frame per camera.
Midpoint and last-frame posters of one camera (QUA-1840).
object
Camera key.
Signed URI of the midpoint frame of the window ingest recorded. An edit and a split piece keep their take’s posters, so after a trim or a split this frame may lie outside the episode’s own frames. The field name is retained for compatibility; ingest publishes a midpoint, not a first frame.
Signed URI of the last frame of the window ingest recorded; like the midpoint, it is the take’s after a trim or a split.
Task label (editable).
Language instruction (editable).
Operator label.
Recording rig key, as the recording carries it (see Rig.key).
Accounts/{account}/robots/{robot}: the fleet robot it was recorded on.
Legacy single-method projection retained for older clients.
Canonical collection-method tags (teleop, vr, umi, egocentric, policy-rollout, sim). Multiple tags may describe one episode.
Scene label (editable).
Recorder session id.
Free tags (editable).
How the attempt went (editable; the operator’s own mark by default).
Who set the outcome.
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.
Recorder markers.
A recorder marker, e.g. the operator’s success button.
object
Seconds from the start of the recording.
Its label.
Its role (start, end, success, event).
The trim window; unset means untrimmed (editable).
object
First second kept.
Last second kept.
Subtask spans (editable).
One subtask span (QUA-1794).
object
Start, in seconds from the start of the recording.
End, in seconds.
The subtask’s one name (also one of the episode’s tags).
Proposed, accepted or rejected.
Who proposed it.
Health metrics and judgements.
object
Length, seconds (after trim).
Standard deviation of per-frame speed.
Mean joint speed.
Spectral arc length (smoothness; closer to 0 is smoother).
Log dimensionless jerk.
Share of power above the high-frequency cut.
Share of time the arm is idle.
Start pose distance from its robot’s median start, in MADs.
End pose distance from its robot’s median end, in MADs.
Lag between action and state, milliseconds.
Corrections near gripper events.
Gripper open or close events.
Camera motion against joint speed offset, milliseconds (camera lag): the camera_lags entry the panel opens on (a recorded one, else the trusted estimate with the strongest peak).
Mean jerk of the joints (the curation fence’s jerk_mean).
Gripper open-close flickers.
Psd_hf_ratio or tremor above p90 of its robot’s population.
At least one correction.
Composite grade.
Every camera’s offset, by camera key; empty until measured.
One camera’s time offset against the robot’s motion (QUA-2255, QUA-2371): what the camera lag panel shows per camera.
object
Camera key.
Milliseconds; positive when the video runs behind the robot’s motion, negative when it runs ahead.
For an estimate, the correlation peak (-1 to 1); 1 when recorded.
How it was measured, e.g. “motion_xcorr/1” or “sync_event”.
Estimated or recorded.
An estimate whose peak is strong and whose two halves of the episode agree; always true when recorded. Only trusted offsets are judged.
The take as recorded, before curation (QUA-3539): its measurements
(speed, jerk, smoothness, pauses, gripper events, corrections, alignment)
over its whole recording, measured once; a split’s piece has its take’s.
duration_seconds is the recording’s length. Unset until measured; filter
as original.<field>.
object
Length, seconds (after trim).
Standard deviation of per-frame speed.
Mean joint speed.
Spectral arc length (smoothness; closer to 0 is smoother).
Log dimensionless jerk.
Share of power above the high-frequency cut.
Share of time the arm is idle.
Start pose distance from its robot’s median start, in MADs.
End pose distance from its robot’s median end, in MADs.
Lag between action and state, milliseconds.
Corrections near gripper events.
Gripper open or close events.
Camera motion against joint speed offset, milliseconds (camera lag): the camera_lags entry the panel opens on (a recorded one, else the trusted estimate with the strongest peak).
Mean jerk of the joints (the curation fence’s jerk_mean).
Gripper open-close flickers.
Psd_hf_ratio or tremor above p90 of its robot’s population.
At least one correction.
Composite grade.
Every camera’s offset, by camera key; empty until measured.
One camera’s time offset against the robot’s motion (QUA-2255, QUA-2371): what the camera lag panel shows per camera.
object
Camera key.
Milliseconds; positive when the video runs behind the robot’s motion, negative when it runs ahead.
For an estimate, the correlation peak (-1 to 1); 1 when recorded.
How it was measured, e.g. “motion_xcorr/1” or “sync_event”.
Estimated or recorded.
An estimate whose peak is strong and whose two halves of the episode agree; always true when recorded. Only trusted offsets are judged.
The episode as curated: the same measurements over the window it trains
on (after its trim; a piece’s own window), measured when the trim or
split is applied, or else within minutes of the publish that made it.
duration_seconds is after the trim. Unset until measured, and for a
revision no upload holds now; filter as curated.<field>.
object
Length, seconds (after trim).
Standard deviation of per-frame speed.
Mean joint speed.
Spectral arc length (smoothness; closer to 0 is smoother).
Log dimensionless jerk.
Share of power above the high-frequency cut.
Share of time the arm is idle.
Start pose distance from its robot’s median start, in MADs.
End pose distance from its robot’s median end, in MADs.
Lag between action and state, milliseconds.
Corrections near gripper events.
Gripper open or close events.
Camera motion against joint speed offset, milliseconds (camera lag): the camera_lags entry the panel opens on (a recorded one, else the trusted estimate with the strongest peak).
Mean jerk of the joints (the curation fence’s jerk_mean).
Gripper open-close flickers.
Psd_hf_ratio or tremor above p90 of its robot’s population.
At least one correction.
Composite grade.
Every camera’s offset, by camera key; empty until measured.
One camera’s time offset against the robot’s motion (QUA-2255, QUA-2371): what the camera lag panel shows per camera.
object
Camera key.
Milliseconds; positive when the video runs behind the robot’s motion, negative when it runs ahead.
For an estimate, the correlation peak (-1 to 1); 1 when recorded.
How it was measured, e.g. “motion_xcorr/1” or “sync_event”.
Estimated or recorded.
An estimate whose peak is strong and whose two halves of the episode agree; always true when recorded. Only trusted offsets are judged.
Content revision of the episode edit chain (trim, subtasks, tags, …).
Sent back on UpdateEpisodes; equals the revision.
When it was ingested.
When its content or standing last changed.
Read through a mixture: where it stands upstream (the least settled of its upload and any mixture in between). Unset in its upload’s scope.
How the take moves; set only in the EPISODE_VIEW_ANALYSIS view.
object
The definition the numbers follow; a reader treats another one as not measured yet.
Why the take could not be measured: “no_joints” (no state) or “channel_never_read”. Empty when measured.
Rows per second it was measured at.
Rows read.
Variance of the joint speed over every state channel, (units/s)^2.
Mean joint speed over every state channel, units/s.
Mean norm of the state’s third difference, units/s^3.
Share of the speed spectrum’s power above 3 Hz.
Share of frames under 5% of the top speed.
Mean |v_smooth - v| / (|v_smooth| + |v|) over the arm joints.
Commanded gripper moves of at least 30% of their travel.
The most events of one gripper inside 0.5 s.
Regrasps within 3 s, plus events the arm retraces its approach round.
State channel names, in the order of the poses.
First state row, every channel.
Last state row, every channel.
Every commanded channel, in recording order.
One commanded channel’s training-chart inputs.
object
Channel name, as the recording names it.
The value at 50 evenly spaced points of the take, first to last.
Autocorrelation at lags 1..min(100, frames / 2); empty when the channel never moves, and in a list.
Unset when the state has no channel of this name, and in a list.
object
Correlation at lags -30..30 frames; NaN where a lag has no variance. Empty when the take is under 5 frames.
How the take moves as recorded, before curation: the same numbers over
its whole recording, measured once, with no channels; a split’s piece
has its take’s. Where analysis follows a trim or a split, this stays,
so the outliers tab sets the episodes as curated against the takes as
recorded. Set only in the EPISODE_VIEW_ANALYSIS view, once measured.
object
The definition the numbers follow; a reader treats another one as not measured yet.
Why the take could not be measured: “no_joints” (no state) or “channel_never_read”. Empty when measured.
Rows per second it was measured at.
Rows read.
Variance of the joint speed over every state channel, (units/s)^2.
Mean joint speed over every state channel, units/s.
Mean norm of the state’s third difference, units/s^3.
Share of the speed spectrum’s power above 3 Hz.
Share of frames under 5% of the top speed.
Mean |v_smooth - v| / (|v_smooth| + |v|) over the arm joints.
Commanded gripper moves of at least 30% of their travel.
The most events of one gripper inside 0.5 s.
Regrasps within 3 s, plus events the arm retraces its approach round.
State channel names, in the order of the poses.
First state row, every channel.
Last state row, every channel.
Every commanded channel, in recording order.
One commanded channel’s training-chart inputs.
object
Channel name, as the recording names it.
The value at 50 evenly spaced points of the take, first to last.
Autocorrelation at lags 1..min(100, frames / 2); empty when the channel never moves, and in a list.
Unset when the state has no channel of this name, and in a list.
object
Correlation at lags -30..30 frames; NaN where a lag has no variance. Empty when the take is under 5 frames.
Length of the recording that edits are checked against, in seconds: a subtask or trim may not end after it. It is the stored millisecond length, so it can be shorter than frame_count / fps. Unset on the response an edit replays.
Accounts/{account}/tasks/{task}: the Task the take is recorded against
(QUA-3116), or empty when unlinked. A link, not content: task stays the
label and language instruction training reads, and linking changes no
revision, digest or version. Names a task of the episode’s account
(NOT_FOUND otherwise). Deleting the task unlinks it. Set with AssignTask,
or UpdateEpisodes with the path on its own in one edit. A take with no link of its own
reads the Dataset.linked_task of the dataset that holds it (QUA-3413,
linked_task_inherited): its upload’s, or once a merge took the upload,
the merged dataset’s own (QUA-3511), wherever the take is read from. Its
own link overrides that, and clearing it (UpdateEpisodes with "") makes
the take read the dataset’s again. Filters, facets and the VLM check
read this value.
Whether linked_task is the dataset’s that holds the take (its upload’s, or its merged dataset’s: QUA-3413, QUA-3511): the take has no link of its own. False when nothing links it, or when it links a task itself.
Who is editing the take now; unset when nobody holds a live lease. ListEpisodes and GetEpisode fill it.
object
The holder’s user id (as Actor.user).
The holder’s display name at the time they took it; empty when they have none. (— api-linter: core::0122::name-suffix=disabled aip.dev/not-precedent: a person’s display name, not a resource name; events-api’s lease frames call it this. —)
When it lapses unless renewed.
The take’s draft (EpisodeDraft), its edit not yet in a version; unset when it has none. One per take, so it reads the same from every scope. ListEpisodes and GetEpisode fill it.
object
Who last changed the drawing: a person, or an API key acting for none.
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 drawing was last saved.
Always OPEN: a draft is never applied.
The revision it was drawn on (Episode.revision then).
The pieces the drawing keeps: 1 for a trim, 2 or more for a split (each becomes an episode of the version published from it), 0 when it keeps nothing.
The seconds its kept pieces last, together.
Set on an episode a version published from a draft that cut a take: the take and where in it the episode lies. Unset on a take.
object
Accounts/{account}/datasets/{dataset}/episodes/{episode}: the take it was cut from.
The take’s index in its upload (Episode.index of the take).
Its place among the take’s pieces, from 1.
How many pieces the take was cut into.
Where it starts, in seconds of the take’s recording.
Where it ends, in seconds of the take’s recording.
Empty on the last page.
Episodes matching the filter, across every page.
Example
{ "episodes": [ { "state": "STATE_UNSPECIFIED", "decision": { "verdict": "VERDICT_UNSPECIFIED", "actor": { "kind": "KIND_UNSPECIFIED", "attribution": { "authentication": "AUTHENTICATION_UNSPECIFIED", "credentialOwner": "CREDENTIAL_OWNER_UNSPECIFIED" } } }, "outcome": "OUTCOME_UNSPECIFIED", "outcomeActor": { "kind": "KIND_UNSPECIFIED", "attribution": { "authentication": "AUTHENTICATION_UNSPECIFIED", "credentialOwner": "CREDENTIAL_OWNER_UNSPECIFIED" } }, "subtasks": [ { "review": "REVIEW_UNSPECIFIED", "origin": "ORIGIN_UNSPECIFIED" } ], "metrics": { "qualityTier": "QUALITY_TIER_UNSPECIFIED", "cameraLags": [ { "source": "SOURCE_UNSPECIFIED" } ] }, "originalMetrics": { "qualityTier": "QUALITY_TIER_UNSPECIFIED", "cameraLags": [ { "source": "SOURCE_UNSPECIFIED" } ] }, "curatedMetrics": { "qualityTier": "QUALITY_TIER_UNSPECIFIED", "cameraLags": [ { "source": "SOURCE_UNSPECIFIED" } ] }, "upstreamState": "STATE_UNSPECIFIED", "draft": { "updateActor": { "kind": "KIND_UNSPECIFIED", "attribution": { "authentication": "AUTHENTICATION_UNSPECIFIED", "credentialOwner": "CREDENTIAL_OWNER_UNSPECIFIED" } }, "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" } ]}