<!-- Source: https://medius.k4tech.net/native/commands/requests -->
# Requests

_Query the box for state_

[`QUERY`](/native/commands/requests.md#requests) is the only command that gets a reply, a [`RESP`](/native/commands/requests.md#resp). Pick what to read with the `what` selector: the firmware [version](/native/commands/requests.md#version), the box's [health](/native/commands/requests.md#health), the cloned [device info](/native/commands/requests.md#device-info), [device capabilities](/native/commands/requests.md#caps), [rate](/native/commands/requests.md#rate), delivery [stats](/native/commands/requests.md#stats), the active input [locks](/native/commands/requests.md#locks), the [catch](/native/commands/requests.md#catch) subscription, a persistent box [option](/native/commands/requests.md#options), or the buffered input [clip](/native/commands/requests.md#clip).

## QUERY

_Ask the box for state_

`QUERY` asks for one piece of state, named by its `what` byte. [Opcode](/native/frame.md#opcodes) `0x05`.

```text
QUERY 0x05 · payload 1 byte (2 for OPTIONS)
```

_Returns RESP_

#### PAYLOAD

| Offset | Field | Type | Notes |
| --- | --- | --- | --- |
| 0 | `what` | `u8` | which state to read (see below) |
| 1 | `id` | `u8` | only for `what = 9` (OPTIONS): which option to read; omitted otherwise |

#### SELECTORS

| `what` | Reads | Reply |
| --- | --- | --- |
| `0` | The firmware version. | [`VERSION`](/native/commands/requests.md#version) |
| `1` | The box's health. | [`HEALTH`](/native/commands/requests.md#health) |
| `2` | The cloned device's USB identity, kind, and product. | [`DEVICE_INFO`](/native/commands/requests.md#device-info) |
| `3` | The whole device's capabilities (mouse + keyboard). | [`CAPS`](/native/commands/requests.md#caps) |
| `4` | The native report rate. | [`RATE`](/native/commands/requests.md#rate) |
| `5` | Delivery and telemetry counters. | [`STATS`](/native/commands/requests.md#stats) |
| `6` | The active input locks. | [`LOCKS`](/native/commands/requests.md#locks) |
| `7` | The active catch subscription. | [`CATCH`](/native/commands/requests.md#catch) |
| `8` | reserved | \- |
| `9` | A persistent box option, by `id`. | [`OPTIONS`](/native/commands/requests.md#options) |
| `10` | The buffered-clip ring depth, playback state, and config. | [`CLIP`](/native/commands/requests.md#clip) |

#### EFFECT

The box replies with a [`RESP`](/native/commands/requests.md#resp) carrying the same `what` and the requested data, one per selector in the table above. `QUERY` is the only command that gets a reply; everything else is [fire-and-forget](/native/injection.md#fire-and-forget). Library bindings: [`query_version`](/library/requests.md#version), [`query_health`](/library/requests.md#health), [`device_info`](/library/requests.md#device-info), [`caps`](/library/requests.md#caps), [`query_rate`](/library/requests.md#query-rate), [`query_stats`](/library/requests.md#query-stats), [`query_locks`](/library/requests.md#query-locks), [`query_catch`](/library/requests.md#query-catch), [`query_imperfect`](/library/options.md#query-imperfect), [`query_movement_riding`](/library/options.md#query-movement-riding), [`query_emit_pace`](/library/options.md#query-emit-pace), and the clip [`status`](/library/requests.md#clip-status) query.

#### EXAMPLE

`what = 0` (read the version):

```
+--------+--------+--------+--------+--------+--------+
| A5     | 05     | 00     | 01 00  | 00     | lo hi  |
+--------+--------+--------+--------+--------+--------+
| SOF    | TYPE   | SEQ    | LEN    | what   | CRC16  |
+--------+--------+--------+--------+--------+--------+
```

## RESP

_The box's reply_

`RESP` is the box's reply to a [`QUERY`](/native/commands/requests.md#requests). [Opcode](/native/frame.md#opcodes) `0x06`.

```text
RESP 0x06 · box → PC
```

_Reply_

#### PAYLOAD

| Offset | Field | Type | Notes |
| --- | --- | --- | --- |
| 0 | `what` | `u8` | echoes the request's selector |
| 1.. | `data` | `varies` | the layout for the requested `what` (see the [selectors](/native/commands/requests.md#requests)) |

#### EFFECT

You get exactly one `RESP` per `QUERY`. Its [`SEQ`](/native/frame.md#seq) matches the request's and `what` echoes the selector, so you can pair a reply with its request and tell which kind it is. Each selector's payload is laid out below, with an example frame.

## VERSION

_RESP payload, what = 0_

The [`RESP`](/native/commands/requests.md#resp) payload when `what = 0`. `proto_ver` is the protocol version (this documentation describes `3`); the box reports its own firmware version, then its base `mac`, a stable per-box id, then a length-delimited ASCII [`name`](/native/commands/option.md#name) tail (a synthesized default when unset). The `name` is additive, so `proto_ver` stays `3`: an older box just sends an empty tail.

```text
QUERY what = 0 · RESP 11-byte header + name
```

_Returns RESP_

#### PAYLOAD

| Offset | Field | Type | Notes |
| --- | --- | --- | --- |
| 0 | `what` | `u8` | 0x00 |
| 1 | `proto_ver` | `u8` | protocol version, expected 3 |
| 2 | `fw_major` | `u8` | firmware major |
| 3 | `fw_minor` | `u8` | firmware minor |
| 4 | `fw_patch` | `u8` | firmware patch |
| 5 | `mac` | `u8[6]` | the device chip's base MAC; the stable per-box id, rendered as 12 lowercase hex digits |
| 11.. | `name` | `ascii` | the box's human-readable name, filling the rest of the payload (the frame `LEN` delimits it); a synthesized `Medius-XXXX` default when unset, set via [`OPTION(NAME)`](/native/commands/option.md#name) |

#### EFFECT

The box also sends this unprompted at startup, as a [ready signal](/native/connection.md#hello). The `mac` stays fixed for a box, so it identifies the same box across replugs and port renumbering; the [`name`](/native/commands/option.md#name) is its readable label. Library binding: [`query_version`](/library/requests.md#version).

#### EXAMPLE

Firmware `3.0.0`, protocol `3`, MAC `123456789abc`, name "Loki":

```
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| A5     | 06     | 00     | 0F 00  | 00     | 03     | 03     | 00     | 00     | ...    |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| SOF    | TYPE   | SEQ    | LEN    | what   | proto  | major  | minor  | patch  | ...    |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| ...    | 12 34 56 78 9A BC  | 4C 6F 6B 69  | lo hi  |
+--------+--------------------+--------------+--------+
| ...    | mac (6 bytes)      | "Loki"       | CRC16  |
+--------+--------------------+--------------+--------+
```

## HEALTH

_RESP payload, what = 1_

The [`RESP`](/native/commands/requests.md#resp) payload when `what = 1`: a single `flags` byte, each bit an independent status.

```text
QUERY what = 1 · RESP 2 bytes
```

_Returns RESP_

#### PAYLOAD

| Offset | Field | Type | Notes |
| --- | --- | --- | --- |
| 0 | `what` | `u8` | 0x01 |
| 1 | `flags` | `u8` | the status bits below |

#### FLAGS

| Bit | Mask | Set when |
| --- | --- | --- |
| b0 | `0x01` | the link to the host chip is up |
| b1 | `0x02` | a real mouse is attached |
| b2 | `0x04` | the PC has set up the cloned mouse |
| b3 | `0x08` | [injection](/native/injection.md) is active |
| b4 | `0x10` | `RATE_CONFIDENT`: the native-rate estimator window is full, so the [`RATE`](/native/commands/requests.md#rate) value is trustworthy |
| b5 | `0x20` | `LOCK_ON`: at least one input [`LOCK`](/native/commands/lock.md) is active |
| b6 | `0x40` | `CATCH_ON`: a [`CATCH`](/native/commands/catch.md) subscription is active, physical-input events are streaming |
| b7 | `0x80` | `KBD_ATT`: a keyboard is attached on the host chip, cloned and injectable |

#### EFFECT

The first three bits set means the box is ready for input to reach the PC. Library binding: [`query_health`](/library/requests.md#health).

#### EXAMPLE

Ready, with link, mouse, and clone all up (`flags = 0x07`):

```
+--------+--------+--------+--------+--------+--------+--------+
| A5     | 06     | 00     | 02 00  | 01     | 07     | lo hi  |
+--------+--------+--------+--------+--------+--------+--------+
| SOF    | TYPE   | SEQ    | LEN    | what   | flags  | CRC16  |
+--------+--------+--------+--------+--------+--------+--------+
```

## DEVICE_INFO

_RESP payload, what = 2_

The [`RESP`](/native/commands/requests.md#resp) payload when `what = 2`: the USB identity, kind, and product string the box read from the real device. The clone shows up on the game PC, not here, so this is the only way the control PC can read it. The header is fixed at 11 bytes, then a length-delimited UTF-8 `product` tail (which may be empty). Every field is zero when nothing is attached.

```text
QUERY what = 2 · RESP 11-byte header + product
```

_Returns RESP_

#### PAYLOAD

| Offset | Field | Type | Notes |
| --- | --- | --- | --- |
| 0 | `what` | `u8` | 0x02 |
| 1 | `vid` | `u16` | idVendor, little-endian |
| 3 | `pid` | `u16` | idProduct, little-endian |
| 5 | `bcd_device` | `u16` | bcdDevice, the device release |
| 7 | `bcd_usb` | `u16` | bcdUSB, e.g. 0x0200 or 0x0201 |
| 9 | `flags` | `u8` | the bits below |
| 10 | `primary_kind` | `u8` | the cloned device's kind, from its Boot-interface protocol (see below) |
| 11.. | `product` | `UTF-8` | the product string, filling the rest of the payload; may be empty |

#### FLAGS

| Bit | Mask | Set when |
| --- | --- | --- |
| b0 | `0x01` | `HAS_SERIAL`: the clone serves a serial string |
| b1 | `0x02` | `HAS_BOS`: the clone serves a BOS descriptor |

#### PRIMARY_KIND

| Value | Kind |
| --- | --- |
| `0` | unknown |
| `1` | keyboard |
| `2` | mouse |

#### EFFECT

A `vid` of `0` means nothing is attached yet. Library binding: [`device_info`](/library/requests.md#device-info).

#### EXAMPLE

A Logitech G502 (`046D:C08B`), USB 2.01, serial and BOS served, kind mouse, product "G502":

```
+--------+--------+--------+--------+--------+--------+--------+--------+
| A5     | 06     | 00     | 0F 00  | 02     | 6D 04  | 8B C0  | ...    |
+--------+--------+--------+--------+--------+--------+--------+--------+
| SOF    | TYPE   | SEQ    | LEN    | what   | vid    | pid    | ...    |
+--------+--------+--------+--------+--------+--------+--------+--------+
| ...    | 10 01  | 01 02  | 03     | 02     | 47 35 30 32  | lo hi  |
+--------+--------+--------+--------+--------+--------------+--------+
| ...    | bcdDev | bcdUSB | flags  | kind   | "G502"       | CRC16  |
+--------+--------+--------+--------+--------+--------------+--------+
```

## CAPS

_RESP payload, what = 3_

The [`RESP`](/native/commands/requests.md#resp) payload when `what = 3`: one summary of the whole cloned device, mouse and keyboard, read from its HID report descriptors. Counts and yes/no flags only, never raw HID field offsets. Use it to check before you act: an [`INJECT`](/native/commands/inject.md#inject) for a usage the device lacks is silently ignored, so the counts tell you what is real. A class that is not present reads all-zero.

```text
QUERY what = 3 · RESP 7 bytes
```

_Returns RESP_

#### PAYLOAD

| Offset | Field | Type | Notes |
| --- | --- | --- | --- |
| 0 | `what` | `u8` | 0x03 |
| 1 | `n_buttons` | `u8` | buttons the mouse report carries |
| 2 | `axis_flags` | `u8` | mouse axes, the bits below |
| 3 | `n_hid` | `u8` | cloned HID interfaces; >1 = composite |
| 4 | `n_keys` | `u8` | keycode-array slots, or 0xFF for NKRO; 0 = no keyboard |
| 5 | `kbd_flags` | `u8` | keyboard, the bits below |
| 6 | `change_driven` | `u8` | per class: b0 mouse (continuous, 0), b1 keyboard/media (change-driven, 1 when bound) |

#### AXIS_FLAGS

| Bit | Mask | Set when |
| --- | --- | --- |
| b0 | `0x01` | `X`: the report carries an X axis |
| b1 | `0x02` | `Y`: the report carries a Y axis |
| b2 | `0x04` | `WHEEL`: the report carries a wheel |
| b3 | `0x08` | `REPORT_ID`: the mouse report sits behind a HID report ID |

#### KBD_FLAGS

| Bit | Mask | Set when |
| --- | --- | --- |
| b0 | `0x01` | `NKRO`: the keyboard reports an NKRO bitmap |
| b1 | `0x02` | `CONSUMER`: a Consumer collection is present, so media keys are injectable |
| b2 | `0x04` | `SYSTEM`: a system-control collection is present (passthrough-only) |
| b3 | `0x08` | `REPORT_ID`: the keyboard report sits behind a HID report ID |

#### EFFECT

Library binding: [`caps`](/library/requests.md#caps).

#### EXAMPLE

A 5-button mouse (X/Y/wheel, one interface) plus a 6-key Consumer keyboard (`axis_flags = 0x07`, `kbd_flags = 0x02`, keyboard change-driven):

```
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| A5     | 06     | 00     | 07 00  | 03     | 05     | 07     | 01     | 06     | 02     | 02     | lo hi  |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| SOF    | TYPE   | SEQ    | LEN    | what   | n_btn  | axis   | n_hid  | n_keys | kbdfl  | chgdrv | CRC16  |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
```

## RATE

_RESP payload, what = 4_

The [`RESP`](/native/commands/requests.md#resp) payload when `what = 4`: how fast the active input reports, plus the poll period the clone advertises. The answer is class-aware, so read the field that fits the input kind:

| Input kind | `CHANGE_DRIVEN` | Read | Gives |
| --- | --- | --- | --- |
| continuous (moving mouse) | `0` | `native_period_us` | Hz = 1e6 / period; reads 0 until learned |
| change-driven (keyboard, media) | `1` | `poll_period_us` | no steady cadence, so `native_period_us` is 0 |

```text
QUERY what = 4 · RESP 6 bytes
```

_Returns RESP_

#### PAYLOAD

| Offset | Field | Type | Notes |
| --- | --- | --- | --- |
| 0 | `what` | `u8` | 0x04 |
| 1 | `native_period_us` | `u16` | realised native period in µs; 0 = not learned, or change-driven (see flags), Hz = 1e6/period |
| 3 | `poll_period_us` | `u16` | cloned inject-endpoint bInterval poll period in µs; the honest figure for a change-driven input |
| 5 | `flags` | `u8` | the bits below |

#### FLAGS

| Bit | Mask | Set when |
| --- | --- | --- |
| b0 | `0x01` | `CONFIDENT`: the estimator window is full, same source as HEALTH [`RATE_CONFIDENT`](/native/commands/requests.md#health) |
| b1 | `0x02` | `CHANGE_DRIVEN`: the active input is event-driven (keyboard / media), so there is no continuous cadence and `native_period_us` is 0 |

#### EFFECT

A 1 kHz mouse reads ~1000 µs once learned. Library binding: [`query_rate`](/library/requests.md#query-rate).

#### EXAMPLE

A 1 kHz mouse, 1000 µs poll, estimator confident (`flags = 0x01`):

```
+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| A5     | 06     | 00     | 06 00  | 04     | E8 03  | E8 03  | 01     | lo hi  |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| SOF    | TYPE   | SEQ    | LEN    | what   | native | poll   | flags  | CRC16  |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+
```

## STATS

_RESP payload, what = 5_

The [`RESP`](/native/commands/requests.md#resp) payload when `what = 5`: counters the box keeps about whether your commands were delivered. Commands are [fire-and-forget](/native/injection.md#fire-and-forget) with no acknowledgement, so these counters are the only way to tell that everything you sent landed. A nonzero `tx_drops` or `tx_wedges` means delivery slipped under load. Wide counters clamp at their max instead of wrapping around.

```text
QUERY what = 5 · RESP 17 bytes
```

_Returns RESP_

#### PAYLOAD

| Offset | Field | Type | Notes |
| --- | --- | --- | --- |
| 0 | `what` | `u8` | 0x05 |
| 1 | `inject_emits` | `u32` | pure-injection reports emitted, little-endian |
| 5 | `tx_drops` | `u16` | reports dropped on TX-queue overflow; should stay 0 |
| 7 | `tx_merges` | `u16` | backed-up reports merged instead of queued |
| 9 | `tx_maxdepth` | `u8` | deepest the TX queue has reached |
| 10 | `tx_wedges` | `u8` | wedged-endpoint recoveries |
| 11 | `wakeups` | `u16` | remote-wakeups issued |
| 13 | `reset_count` | `u16` | USB bus resets seen |
| 15 | `config_count` | `u16` | SET\_CONFIGURATION events (re-enumerations) |

#### EFFECT

`inject_emits` counts the no-halving / 1 kHz path. The rest are merge, queue, wakeup, reset, and reconfig counters. Library binding: [`query_stats`](/library/requests.md#query-stats).

#### EXAMPLE

4096 emits, no drops, no wedges:

```
+--------+--------+--------+--------+--------+--------------+
| A5     | 06     | 00     | 11 00  | 05     | 00 10 00 00  |
+--------+--------+--------+--------+--------+--------------+
| SOF    | TYPE   | SEQ    | LEN    | what   | inject_emits |
+--------+--------+--------+--------+--------+--------------+
| 00 00  | 00 00  | 00     | 00     | 00 00  | 00 00  | 00 00  | lo hi  |
+--------+--------+--------+--------+--------+--------+--------+--------+
| drops  | merges | maxdep | wedges | wakeup | resets | config | CRC16  |
+--------+--------+--------+--------+--------+--------+--------+--------+
```

## LOCKS

_RESP payload, what = 6_

The [`RESP`](/native/commands/requests.md#resp) payload when `what = 6`: which physical inputs are currently locked by [`LOCK`](/native/commands/lock.md), as a variable list of entries, one per locked field across every class, so keyboard and media locks read the same as mouse ones. An empty list (`n = 0`) means nothing is locked.

```text
QUERY what = 6 · RESP 2 + 4n bytes
```

_Returns RESP_

#### PAYLOAD

| Offset | Field | Type | Notes |
| --- | --- | --- | --- |
| 0 | `what` | `u8` | 0x06 |
| 1 | `n` | `u8` | number of lock entries that follow |
| + | `class` | `u8` | per entry: 0=button 1=key 2=media 3=axis (as [`LOCK`](/native/commands/lock.md)) |
| + | `id` | `u16` | the locked field's id, or 0xFFFF for a whole-class blanket, little-endian |
| + | `dirbits` | `u8` | which edges are locked, the bits below |

#### DIRBITS

| Bit | Mask | Set when |
| --- | --- | --- |
| b0 | `0x01` | the positive / press edge is locked |
| b1 | `0x02` | the negative / release edge is locked |

#### EFFECT

Read it to confirm a lock landed, or to mirror the box's lock state in a UI. Library binding: [`query_locks`](/library/requests.md#query-locks).

#### EXAMPLE

One entry: the wheel's negative (scroll-down) sign locked (`class = 3` axis, `id = 2` wheel, `dirbits = 0x02`):

```
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| A5     | 06     | 00     | 06 00  | 06     | 01     | 03     | 02 00  | 02     | lo hi  |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| SOF    | TYPE   | SEQ    | LEN    | what   | n      | class  | id     | dirbits| CRC16  |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
```

## CATCH

_RESP payload, what = 7_

The [`RESP`](/native/commands/requests.md#resp) payload when `what = 7`: the active [`CATCH`](/native/commands/catch.md) subscription `mask`, plus the box-side count of event frames dropped under back-pressure. A zero mask means nothing is subscribed. Mirrors the [`CATCH_ON`](/native/commands/requests.md#health) health bit.

```text
QUERY what = 7 · RESP 6 bytes
```

_Returns RESP_

#### PAYLOAD

| Offset | Field | Type | Notes |
| --- | --- | --- | --- |
| 0 | `what` | `u8` | 0x07 |
| 1 | `mask` | `u8` | subscribed event classes; bits Motion 0x01, Wheel 0x02, Buttons 0x04, Keys 0x08, Media 0x10 |
| 2 | `dropped` | `u32` | events dropped box-side under back-pressure, little-endian |

#### EFFECT

Read it to confirm a subscription landed, or to check whether you're losing events. Library binding: [`query_catch`](/library/requests.md#query-catch).

#### EXAMPLE

Motion and buttons subscribed, no drops (`mask = 0x05`):

```
+--------+--------+--------+--------+--------+--------+--------------+--------+
| A5     | 06     | 00     | 06 00  | 07     | 05     | 00 00 00 00  | lo hi  |
+--------+--------+--------+--------+--------+--------+--------------+--------+
| SOF    | TYPE   | SEQ    | LEN    | what   | mask   | dropped      | CRC16  |
+--------+--------+--------+--------+--------+--------+--------------+--------+
```

## OPTIONS

_RESP payload, what = 9_

The [`RESP`](/native/commands/requests.md#resp) payload when `what = 9`: the value of one persistent box [`OPTION`](/native/commands/option.md), echoing the queried `id`. The value is id-specific, so the query takes the option's `id` as a second byte and each option is read on its own. An unknown id gets no reply.

```text
QUERY what = 9, id · RESP varies
```

_Returns RESP_

#### PAYLOAD

| Offset | Field | Type | Notes |
| --- | --- | --- | --- |
| 0 | `what` | `u8` | 0x09 |
| 1 | `id` | `u8` | which option this value is for |
| 2.. | `value` | `varies` | id-specific, mirroring the matching [`OPTION`](/native/commands/option.md) value |

#### IMPERFECT VALUE

The [`IMPERFECT`](/native/commands/option.md#imperfect) opt-in (id 0) plus two derived clone-status bytes. Each is `0` or `1`; a faithful clone reads all-zero.

| Offset | Field | Notes |
| --- | --- | --- |
| 2 | `allowed` | the opt-in toggle; `1` = cloning an over-capacity device is allowed |
| 3 | `over_capacity` | the attached device needs an interrupt-IN endpoint the box can't service |
| 4 | `clone_imperfect` | the live clone is over-capacity and was cloned anyway, so one interface is dead |

Read it to tell why a clone is missing (`over_capacity = 1`, `allowed = 0`), or to confirm an imperfect clone is live (`clone_imperfect = 1`). Library binding: [`query_imperfect`](/library/options.md#query-imperfect).

#### MOVE_RIDE VALUE

The current [`MOVE_RIDE`](/native/commands/option.md#move-ride) window (id 1).

| Offset | Field | Notes |
| --- | --- | --- |
| 2 | `timeout` | `u16`, little-endian; the ride window in ms, `0` = off |

Library binding: [`query_movement_riding`](/library/options.md#query-movement-riding).

#### EMIT VALUE

The current [`EMIT`](/native/commands/option.md#emit) pacing (id 2): the mode, the configured fixed rate, and the rate actually in effect.

| Offset | Field | Notes |
| --- | --- | --- |
| 2 | `mode` | `0` learnt, `1` interval, `2` fixed |
| 3 | `fixed_hz` | `u16`, little-endian; the configured fixed rate |
| 5 | `resolved_hz` | `u16`, little-endian; the ceiling in effect, `0` = learnt/adaptive or no device yet |

Library binding: [`query_emit_pace`](/library/options.md#query-emit-pace).

#### EXAMPLE

Reading `id = 0`: opted in, an over-capacity device attached and cloned imperfectly:

```
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| A5     | 06     | 00     | 05 00  | 09     | 00     | 01     | 01     | 01     | lo hi  |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| SOF    | TYPE   | SEQ    | LEN    | what   | id     | allow  | overcap| imperf | CRC16  |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+--------+
```

## CLIP

_RESP payload, what = 10_

The [`RESP`](/native/commands/requests.md#resp) payload when `what = 10`: the buffered-clip ring depth, playback state, and full config, for host flow-control. A fixed 25-byte prefix, then the clip's held-usage snapshot (the same class-tagged list a [`USAGE_EVENT`](/native/commands/catch.md#usage-event) carries), then the config tail (autolock, flags, and the bound triggers). Read `free` before a [`CLIP_APPEND`](/native/commands/clip.md#append) to avoid an overrun, and `state` to see a fault or that playback finished. Backs [`ClipHandle::query_status`](/library/requests.md#clip-status) and [`query_config`](/library/requests.md#clip-config).

```text
QUERY what = 10 · RESP 25-byte prefix + held usages + config
```

_Returns RESP_

#### PAYLOAD

| Offset | Field | Type | Notes |
| --- | --- | --- | --- |
| 0 | `what` | `u8` | 10 |
| 1 | `state` | `u8` | 0 idle / 1 playing / 2 paused / 3 faulted (recover with `CLEAR`) |
| 2 | `free` | `u32` | ring bytes free; pace top-ups off this, little-endian |
| 6 | `total` | `u32` | retained clip size in bytes (streaming: buffered-but-undrained bytes) |
| 10 | `played` | `u32` | bytes played from the clip start (retained progress; ~0 while streaming) |
| 14 | `ticks` | `u32` | content ticks emitted since start (diagnostic) |
| 18 | `underruns` | `u16` | empty-ring episodes |
| 20 | `overruns` | `u16` | appends dropped whole because the ring was full |
| 22 | `seq_gaps` | `u16` | dropped `CLIP_APPEND` frames detected (SEQ gaps) |
| 24 | `held_n` | `u8` | number of held usages that follow |
| + | `class` | `u8` | per held usage: 0=button 1=key 2=media |
| + | `id` | `u16` | the held usage's id (button id, HID keycode, or Consumer usage), little-endian |
| + | `autolock` | `u8` | config: the [`CLIP_SET`](/native/commands/clip.md#set) autolock bitmask (`CLIP_LOCK_*`) |
| + | `flags` | `u8` | config: b0 loop, b1 retain, b2 finalized |
| + | `n_trig` | `u8` | config: number of bound triggers that follow |
| + | `class` | `u8` | per trigger: 0=button 1=key 2=media 0xFF=any |
| + | `id` | `u16` | per trigger: the usage id, 0xFFFF=any, little-endian |
| + | `edge` | `u8` | per trigger: 0 both / 1 press / 2 release |
| + | `action` | `u8` | per trigger: the [`CLIP_CTRL`](/native/commands/clip.md#ctrl) op 0..5 (start/stop/pause/resume/restart/toggle) |
| + | `consume` | `u8` | per trigger: 1 = swallow the triggering edge from the host |

#### FLAGS

| Bit | Mask | Set when |
| --- | --- | --- |
| b0 | `0x01` | `LOOP`: playback restarts from the top on drain instead of stopping |
| b1 | `0x02` | `RETAIN`: the buffered content survives a stop instead of clearing |
| b2 | `0x04` | `FINALIZED`: the clip is sealed, no more [`CLIP_APPEND`](/native/commands/clip.md#append) accepted |

#### EFFECT

The held snapshot lists the usages the clip is currently forcing down, one class-tagged entry each (3 bytes), so buttons, keys, and media are reported one way. The config tail mirrors what [`CLIP_SET`](/native/commands/clip.md#set) and [`CLIP_TRIGGER`](/native/commands/clip.md#trigger) set, so a UI can read back the whole clip in one query. Library bindings: [`query_status`](/library/requests.md#clip-status) ([`ClipStatus`](/library/types/structs.md#clip-status)) and [`query_config`](/library/requests.md#clip-config) ([`ClipSettings`](/library/types/structs.md#clip-settings)).

#### EXAMPLE

Idle, empty ring, no held usages, no autolock, no triggers (`state = 0`, `free = 1024`):

```
+--------+--------+--------+--------+--------+--------+--------------+
| A5     | 06     | 00     | 1C 00  | 0A     | 00     | 00 04 00 00  |
+--------+--------+--------+--------+--------+--------+--------------+
| SOF    | TYPE   | SEQ    | LEN    | what   | state  | free         |
+--------+--------+--------+--------+--------+--------+--------------+
| 00 04 00 00  | 00 00 00 00  | 00 00 00 00  | 00 00  | 00 00  | 00 00  |
+--------------+--------------+--------------+--------+--------+--------+
| total        | played       | ticks        | undrun | ovrrun | seqgap |
+--------------+--------------+--------------+--------+--------+--------+
| 00     | 00     | 00     | 00     | lo hi  |
+--------+--------+--------+--------+--------+
| held_n | autolk | flags  | n_trig | CRC16  |
+--------+--------+--------+--------+--------+
```
