# Data model

The data structures your client receives. Units are **meters**; rotations are **quaternions `(x, y, z, w)`**; positions are **world space** unless noted.

## Skeleton

A tracked person for one frame.

| Field | Type | Notes |
|-------|------|-------|
| `Id` | string | Per-frame/session instance id |
| `EntityId` | string | **Stable** identity (set during entity registration) |
| `AnchorId` | string | Anchor the skeleton is positioned against |
| `Positions` | float[25 × 3] | Joint positions (x, y, z) in meters, world space |
| `Confidence` | float[25] | Per-joint confidence 0–1 |
| `CaptureTime` | double | Unix timestamp (s, fractional) — use to sync streams |
| `HeadLocalRotation` | quaternion | Device-local head orientation |
| `LeftHand* / RightHand*` | bytes | Hand joint positions/rotations (when hands enabled) |
| `Controller info` | — | VR controller state, when present |

### Joints (25)

Nose · Neck · Shoulders (L/R) · Elbows (L/R) · Wrists (L/R) · Hips (L/R) · Knees (L/R) · Ankles (L/R) · Eyes (L/R) · Ears (L/R) · Toes / heels (L/R).

> Hands add **21 key points each**. A full body-plus-hands point set is **25 + 21×2 = 67** points — this is the `positions_67` layout you'll see in exports.

## Tracked objects

| Type | Key fields |
|------|-----------|
| **Marker** | `Id`, `Type`, `Position`, `Radius` |
| **Object** | `Id`, `Name`, `Position`, `Rotation`, `MarkerIds[]` |

Objects are composed from markers (e.g. a ball built from a colored marker).

## Camera

| Field | Notes |
|-------|-------|
| `Id` | Camera identifier |
| `Intrinsic` | 3×3 camera matrix |
| `Extrinsic` | 4×4 pose |
| `Distortion` | Lens coefficients |
| `Width` / `Height` / `FrameRate` | Stream properties |

## Spatial

| Type | Fields |
|------|--------|
| **Anchor** | `AnchorId`, `Position`, `Rotation`, `ParentId`, `Visible` |
| **Guardian** | `GuardianId`, `Points[]`, `Height` (play-space boundary) |

:::tip
`EntityId` is the field you want for "is this the same person as before?" — `Id` can change frame to frame; `EntityId` is stable once the person is registered.
:::
