# Checks_ReadReachTrace

`GET /v1/accounts/{account}/checks/{check}/results/{result}:readReachTrace`

Read one result's bounded sampled solver joint trace. The key must still
be current for the episode's target robot and settings (or be the key
ReadReachTracesRequest.expected_key also admits); a stale key is
FAILED_PRECONDITION, and a trace that could not be read just now is
UNAVAILABLE. `max_frames` is at most 512 (0 means 512).

- Base URL: `https://junction-api.qualiastudios.dev`
- Authentication: an API key in the `X-API-Key` header

## Parameters

- `account` (path, string, required): The account id.
- `check` (path, string, required): The check id.
- `result` (path, string, required): The result id.
- `expectedKey` (query, string): The key from CheckResult.reach.trace. A stale trace is refused.
- `maxFrames` (query, integer (int32)): At most 512 samples. 0 means the maximum.
- `dataset` (query, string): Current dataset scope whose settings and pose/calibration identity must
  still produce expected_key; this prevents reading an old shared result
  after placement changes in an upload or any member of a merged dataset.

## Responses

- `200` OK: `application/json` `qualia.v1.ReadReachTraceResponse`
- `default` Default error response: `application/json` `google.rpc.Status`

## Schemas

```yaml
qualia.v1.ReadReachTraceResponse:
  type: object
  properties:
    key:
      type: string
      description: The current reach key this trace belongs to.
    robot:
      type: string
      description: The target robot whose URDF joints appear in each frame.
    configDigest:
      type: string
      description: Robot model digest the solver used.
    poseSource:
      enum:
        - POSES_AT_UNSPECIFIED
        - ROOT
        - TCP
      type: string
      description: Where the source hand poses were recorded.
      format: enum
    calibrationDigest:
      type: string
      description: Calibration digest already applied to TCP channels, empty at root.
    placementDigest:
      type: string
      description: Digest of the fixed-base placement settings.
    frameCount:
      type: integer
      description: Number of frames in the original take.
      format: int32
    sampleEvery:
      type: integer
      description: Number of original input rows between retained solver frames.
      format: int32
    fps:
      type: number
      description: Source take's frames per second.
      format: double
    jointNames:
      type: array
      items:
        type: string
      description: Actuated URDF joints in the exact order used by each joint_positions row.
    homeMidpointM:
      type: array
      items:
        type: number
        format: double
      description: Mean of both hand positions at solver home, in fixed-base metres.
    frames:
      type: array
      items:
        $ref: "#/components/schemas/qualia.v1.ReachTraceFrame"
      description: Bounded samples with original row indices and reach flags.
    armBounds:
      type: array
      items:
        $ref: "#/components/schemas/qualia.v1.ReachArmBound"
      description: Conservative URDF bounds, carried once rather than repeated in every row.
    gaps:
      type: array
      items:
        $ref: "#/components/schemas/qualia.v1.ReachPoseGap"
      description: Every missing-pose interval. Never interpolate a posture across one.
  description: A bounded sampled solver posture trace for one episode.
qualia.v1.ReachTraceFrame:
  type: object
  properties:
    index:
      type: integer
      description: Index in the original take, before the trace's bounded stride.
      format: int32
    seconds:
      type: number
      description: Seconds from the start of the take.
      format: double
    jointPositions:
      type: array
      items:
        type: number
        format: double
      description: One position per response joint_names, in URDF joint order.
    reachable:
      type: boolean
      description: Whether every targeted hand pose in this frame met the reach tolerance.
    valid:
      type: boolean
      description: False means the frame must not be replayed as a solved posture.
    diagnostics:
      allOf:
        - $ref: "#/components/schemas/qualia.v1.ReachFrameDiagnostics"
      description: Local measured causes at this exact sampled row, never interpolated.
  description: One frame of a solver posture trace.
qualia.v1.ReachFrameDiagnostics:
  type: object
  properties:
    sides:
      type: array
      items:
        $ref: "#/components/schemas/qualia.v1.ReachSideDiagnostics"
      description: Only hands that missed their target in this row.
  description: Causes measured at the exact retained input row.
qualia.v1.ReachSideDiagnostics:
  type: object
  properties:
    side:
      enum:
        - SIDE_UNSPECIFIED
        - SIDE_LEFT
        - SIDE_RIGHT
      type: string
      description: Configured hand side.
      format: enum
    heldJoints:
      type: array
      items:
        $ref: "#/components/schemas/qualia.v1.ReachHeldJoint"
      description: Locally limiting joints, with actual URDF attribution.
    beyondChainReach:
      allOf:
        - $ref: "#/components/schemas/qualia.v1.ReachBeyondReach"
      description: Present only when a finite fixed-anchor outer bound proves the excess.
    residualSolverMiss:
      type: boolean
      description: Solver left a miss without either of the measured causes above.
  description: Factual diagnostics for one missed hand at one sampled posture.
qualia.v1.ReachHeldJoint:
  type: object
  properties:
    joint:
      type: string
      description: Actual URDF joint and the link it turns.
    childLink:
      type: string
      description: Actual URDF child link.
    bound:
      type: string
      description: '"lower" or "upper".'
    position:
      type: number
      description: Measured position in radians (metres for prismatic).
      format: double
    limit:
      type: number
      description: The active URDF limit, in the same native joint unit.
      format: double
    outwardErrorDecrease:
      type: number
      description: |-
        Decrease of tolerance-normalized squared error per native joint unit in
        the direction beyond this bound. Positive, measured from actual FK.
      format: double
  description: |-
    A finite active joint bound whose outward differential reduces target error.
    This is local constraint evidence, not proof that every IK branch fails.
qualia.v1.ReachBeyondReach:
  type: object
  properties:
    distanceMeters:
      type: number
      description: Target distance from the shoulder, metres.
      format: double
    radiusMeters:
      type: number
      description: Conservative chain radius, metres.
      format: double
    excessMeters:
      type: number
      description: Target distance minus radius minus the existing position tolerance.
      format: double
  description: A target outside a proved fixed-anchor bound by more than reached tolerance.
qualia.v1.ReachArmBound:
  type: object
  properties:
    side:
      enum:
        - SIDE_UNSPECIFIED
        - SIDE_LEFT
        - SIDE_RIGHT
      type: string
      description: Configured arm side.
      format: enum
    shoulderJoint:
      type: string
      description: Actual first independent arm joint.
    parentLink:
      type: string
      description: Parent link containing the shoulder origin.
    shoulderOriginMeters:
      type: array
      items:
        type: number
        format: double
      description: Three metres in that parent link's frame.
    radiusMeters:
      type: number
      description: |-
        Sum of downstream translation lengths and tool offset; finite prismatic
        excursion is included. Inside this sphere does not establish reachability.
      format: double
    baseFixedAnchor:
      type: boolean
      description: Only a base-fixed anchor can prove global beyond-chain reach.
  description: A conservative outer sphere derived from the configured URDF chain/tool.
qualia.v1.ReachPoseGap:
  type: object
  properties:
    startFrame:
      type: integer
      description: First original input row, zero based.
      format: int32
    frameCount:
      type: integer
      description: Consecutive missing-pose rows in this interval.
      format: int32
    startSeconds:
      type: number
      description: Start on the original take's clock, derived from its FPS.
      format: double
    durationSeconds:
      type: number
      description: Length on that clock; the end is exclusive.
      format: double
  description: A gap in the original take's pose coverage, independent of sampled postures.
google.rpc.Status:
  oneOf:
    - $ref: "#/components/schemas/ApiError"
    - $ref: "#/components/schemas/GatewayError"
  description: "The body of a failed call: one of the two shapes below."
ApiError:
  title: API error
  type: object
  required:
    - code
    - message
    - retryable
    - details
  properties:
    code:
      type: string
      description: The gRPC code name in upper case, e.g. `NOT_FOUND`.
    message:
      type: string
    retryable:
      type: boolean
      description: Whether the same call may succeed if retried.
    details:
      type: array
      items:
        type: object
      description: "Empty, except when a dataset copy or move is refused: then one `google.rpc.ErrorInfo` with the refusal's `reason` code, its `domain` and, in `metadata`, the datasets it names."
  description: A refusal from the API itself.
GatewayError:
  title: Gateway error
  type: object
  required:
    - detail
  properties:
    detail:
      type: string
      description: What went wrong.
  description: A refusal from the gateway before the call reaches the API, for example `401` bad or missing API key, `403` key lacks the scope or environment closed, `413` body too large.
```
