kvm workstation
The kvm workstation command configures a seat as a whole: what one operator position is allowed to reach, and how it behaves when video is routed to it.
| Command Type | DisplayNet |
| Minimum Version | 5.0 |
list and show report seats; diagnose explains why one is not working; desk and multiview control what a seat may connect to; follow controls whether routing video to the seat also hands it keyboard and mouse.
Usage
kvm workstation list
kvm workstation show <remote_id>
kvm workstation diagnose <remote_id>
kvm workstation desk add|remove <remote_id> <desk>
kvm workstation desk list <remote_id>
kvm workstation multiview add|remove <remote_id> <config>
kvm workstation multiview list <remote_id>
kvm workstation follow <remote_id> on|off|default
kvm workstation follow default on|off
kvm workstation follow
Subcommands
| Subcommand | Description |
|---|---|
list | One row per seat: the configuration that wins for it, and whether its desk and multiview availability are restricted. Includes seats that have been configured but are not currently powered on. |
show | One seat in full: resolved configuration and its contents, availability lists, follow policy, HID auto-connect, and mouse sensitivity. |
diagnose | Why this seat's keyboard, mouse or control surface is not working, in plain language. Read-only. See Diagnosing a seat. |
desk | Which desks this seat may connect to. See Availability. |
multiview | Which multiview configurations this seat may aim at itself. See Availability. |
follow | Whether routing a source to this seat also gives it keyboard and mouse. See KVM follows video. |
Configuring a seat before it exists
Commands that store configuration accept a seat that is not present; the settings apply the moment the receiver appears. That covers desk, multiview and follow here, and equally kvm streamdeck bind, dial bind, and the kvm config button and dial verbs.
Commands that talk to the hardware need the device online: reset, repaint, status, and the diagnostic probes.
Device '6cdffb00f077' is not currently present — powered off, or not yet on the network.
This command talks to the hardware, so it needs the device online.
(Configuration commands accept a seat that is not present.)
list includes absent seats with "Present": false. show reports a seat that has either hardware or stored configuration, and errors only when it has neither.
Name a not-yet-present seat by its device id, not its name
A seat that is present can be named either way. A seat that is not present can only be named by its device id, the 12-hex-digit form, e.g. 6cdffb00f077.
While the seat is absent its name cannot be resolved, so a command naming it is refused:
'TradingDesk1' is not a known device, and is not shaped like a device id.
Use the seat's name while it is on the network, or its 12-hex-digit device id
to configure it before it is powered on.
A device id is stable, so a binding stored under one attaches to the seat the moment it appears.
Diagnosing a seat
kvm workstation diagnose <remote_id>
Run it when a seat's keyboard, mouse or control surface has stopped working. It is read-only: nothing is re-paired, reset or repainted. A powered-off seat returns the finding that the seat is not on the network, not an error.
Findings
Findings is a list of plain-language sentences; the rest of the response is the evidence behind them.
Findings are ordered causes before consequences, and a finding that fully explains the ones below it is the only one shown. Where a command fixes the problem, the finding names it.
Reading the evidence
| Field | What to look at |
|---|---|
Pairing.Paired | Whether the seat's USB extender is actually paired. This is a live state, not "an extender exists". A seat that has dropped keeps its entry. |
Pairing.AutoConnect | If this is false and Paired is false, that is the cause. See kvm hid. |
Devices | What the receiver currently has mounted, with the product name of each. |
Slots | Which mounted device the keyboard and mouse resolve to. -1 means none of that type. |
Slots.Collapsed | Both roles on one device. Normal for a combined keyboard-and-trackpad, and not on its own a fault. |
Routed | false means the seat controls no host, so input has nowhere to go however healthy the rest is. |
Storms | Descriptor-handshake thrashing. See below. |
Events | Recent per-seat history, oldest first, with SecondsAgo relative to the call. |
EventsRecorded | Everything that has happened, including events already aged out of Events. A large number with a short list is a busy seat, not a quiet one. |
Config | The configuration this seat resolves, or null. A seat with none has no macros and a blank control surface. |
A storm is the USB descriptor handshake repeating dozens of times a second. Every occurrence investigated so far has been a physical fault, most often a failing USB hub, then a marginal cable.
LargestBurst is how big the burst got; larger bursts have meant longer input outages. Try the keyboard and mouse directly in the receiver, bypassing any hub, before looking at configuration.
The history is kept regardless of the server's logging level, so a fault does not need to be reproduced with logging raised.
Per-seat settings
Five settings live on the seat itself rather than in a configuration. They are set by four different commands, but they behave identically.
| Setting | Set it | Reset it |
|---|---|---|
| KVM follows video | kvm workstation follow <rx> on|off | kvm workstation follow <rx> default |
| HID auto-connect | kvm hid enable|disable <rx> | kvm hid clear <rx> |
| Mouse sensitivity | kvm sensitivity <rx> <factor> | kvm sensitivity <rx> default |
| Info-bar branding | kvm streamdeck infobar <rx> on|off | kvm streamdeck infobar <rx> default |
| Deck brightness | kvm streamdeck brightness <rx> <0-100> | kvm streamdeck brightness <rx> default |
Resetting removes the stored value rather than writing the default, so the seat follows any future change to that default. Resetting a seat that has no stored value is a no-op, not an error.
show reports each with a value and a HasOverride flag. A seat set to exactly the default reads identically to one that was never touched; the flag tells them apart.
All five accept a seat that is not present. A seat carrying only these settings, with no bindings, no availability and no assigned config, still appears in list with "Present": false.
kvm workstation list shows every seat with any stored configuration, including ones whose hardware has never been seen. A row with "Present": false and nothing else configured is usually either a seat that has not been racked yet or an identifier that was mistyped once. show reports which settings it carries, and the reset commands above remove them.
Availability
By default every desk connects to every seat, and every multiview configuration is controllable from every seat. Availability narrows that, for a trading desk that should only ever see its own two desks, a lobby seat that should not be able to grab the operations wall.
An empty allow-list means unrestricted, not "nothing allowed"; show reports this as "Restricted": false. Adding the first entry to a seat switches it to restricted, and only what is listed is reachable. Removing the last entry returns it to unrestricted.
An allow-list controls what an operator can aim at a seat. It is not an access-control mechanism and does not stop a multiview that was configured to bring control with it (autoconnectkvm) from doing so. Viewing a multiview at one seat while viewing and controlling it at another is a legitimate setup.
Desks and multiviews are tracked by identity, not by name: renaming one does not break the seats that reference it, and deleting one removes it from those seats.
KVM follows video
By default, routing a source to a seat gives it video only. With follow on, the same route also hands the seat the source's keyboard and mouse.
This seat now drives whatever it displayskvm workstation follow trading_desk_1 on
Any connect to that seat then carries control, whether it came from a Stream Deck button, the source selector, the Controller, or an API client.
Default and states
follow ships off, and the system-wide default is settable separately from each seat:
| Command | Effect |
|---|---|
kvm workstation follow default on | The house default for seats that have not been set individually. |
kvm workstation follow <rx> on | off | An override for this seat that always wins over the default. |
kvm workstation follow <rx> default | Removes the override so the seat inherits again. |
A seat set to off stays off when the default is later turned on. show reports both the effective answer and whether it was inherited.
kvm workstation follow with no arguments reports the default and every seat that overrides it. Seats that inherit are not listed.
Overriding one route
Two options on connect override the policy for a single call:
| Option | Effect |
|---|---|
nokvm | Route video only, even on a seat with follow on. |
withkvm | Carry control, even on a seat with follow off. |
Put this on the seat's screen without taking its keyboardconnect hdmi camera_1 trading_desk_1 nokvm
Cases with no effect
A follow is skipped silently, rather than treated as an error, when there is nothing to hand over:
- the source has no USB host of its own (most sources are video and nothing else);
- the destination is a plain display rather than a seat.
withkvm does not change either case.
If a follow is attempted and fails, whether on a locked device or a receiver that has gone away, the video route still stands and a kvm_autoconnect_warning notification reports why.
Desks
A desk connect routes its monitors and establishes one MultiDevice session across the desk's controllable monitors; it does not trigger per-monitor follows. The desk's controllable setting decides which monitors take control. See kvm desk.
Split transmitters
A DNS transmitter carries the HDMI input and the USB host on the same device. Where a deployment separates the video transmitter from the USB transmitter, tell DisplayNet which pairs with which using kvm hid source.
Rapid switching
Several routes to one seat in quick succession settle into a single session on the last source routed.
Examples
See every seat at a glancekvm workstation list
Everything about one seatkvm workstation show trading_desk_1
Find out why a seat's keyboard has stopped workingkvm workstation diagnose trading_desk_1
Restrict a seat to two deskskvm workstation desk add trading_desk_1 morning_desk
kvm workstation desk add trading_desk_1 evening_desk
Return a seat to unrestrictedkvm workstation desk remove trading_desk_1 morning_desk
kvm workstation desk remove trading_desk_1 evening_desk
Turn on KVM-follows-video everywhere except the lobbykvm workstation follow default on
kvm workstation follow lobby_display off
Return value
kvm workstation show
kvm workstation show trading_desk_1{
"status": "SUCCESS",
"request_id": null,
"result": {
"kvm_workstation": [
{
"RemoteId": "6cdffb00f077",
"Name": "trading_desk_1",
"Present": true,
"HidRemote": true,
"Config": { "Name": "Global", "Macros": 3, "Buttons": 8, "Dials": 0 },
"Desks": { "Restricted": false, "Allowed": [] },
"Multiviews": { "Restricted": false, "Allowed": [] },
"Follow": { "Enabled": false, "Inherited": true },
"Hid": { "AutoConnect": true, "HasOverride": false },
"Sensitivity": { "Factor": 1.0, "HasOverride": false },
"InfoBar": { "Enabled": true, "HasOverride": false },
"Brightness": { "Value": 100, "HasOverride": false }
}
]
},
"error": null
}
HidRemote reports whether this receiver can act on its configuration. A seat can hold macros and buttons without being an HID remote extender, in which case none of them fire.
Every per-seat setting reports its effective value alongside a flag saying whether this seat set it: HasOverride, or Inherited for Follow. See Per-seat settings.
kvm workstation diagnose
A seat whose mouse has stopped working:
kvm workstation diagnose trading_desk_1{
"status": "SUCCESS",
"request_id": null,
"result": {
"kvm_workstation_diagnose": [
{
"RemoteId": "6cdffb00f077",
"Name": "trading_desk_1",
"Present": true,
"Pairing": { "Paired": true, "State": "linked", "AutoConnect": true },
"Devices": [
{ "Index": 1, "Product": "Keychron K10 Pro", "Mouse": false, "Keyboard": true, "ControlSurface": false },
{ "Index": 2, "Product": "Stream Deck XL", "Mouse": false, "Keyboard": false, "ControlSurface": true }
],
"Slots": { "Mouse": -1, "Keyboard": 1, "Collapsed": false },
"Routed": true,
"Storms": { "Count": 3, "LargestBurst": 107, "LastSecondsAgo": 412.6 },
"Events": [
{ "SecondsAgo": 604.1, "Kind": "DeviceSetChanged", "Detail": "0:mouse;1:kb;2:deck" },
{ "SecondsAgo": 412.6, "Kind": "DescriptorStorm", "Detail": "107 answers in 1s" },
{ "SecondsAgo": 411.9, "Kind": "DeviceSetChanged", "Detail": "1:kb;2:deck" }
],
"EventsRecorded": 3,
"Config": "Global",
"Findings": [
"No mouse is resolved for this seat, so pointer input will not be delivered. Check the mouse is plugged into the receiver.",
"The USB descriptor handshake has thrashed 3 times since the engine started (largest burst: 107 in one second), most recently within the last hour. Every occurrence of this investigated so far has been a physical fault — most often a failing USB hub, then a marginal cable. Try the keyboard and mouse directly in the receiver, bypassing any hub.",
"A control surface is attached and a configuration applies to this seat. If its keys are blank or wrong, check the buttons bound for THIS seat with: kvm config show <config>"
]
}
]
},
"error": null
}
In this example the Events list carries the sequence behind the findings: the mouse was present, a storm hit, and the device set came back without it.
A healthy seat returns a single finding:
"Findings": [
"No problems found. This seat is paired, has a keyboard and mouse, is routed to a source, and has a configuration in effect."
]
kvm workstation follow
kvm workstation follow{
"status": "SUCCESS",
"request_id": null,
"result": {
"kvm_workstation_follow": [
{
"Default": true,
"DefaultIsSet": true,
"Overrides": [
{
"RemoteId": "6cdffb00f099",
"Name": "lobby_display",
"Present": true,
"Follow": false
}
]
}
]
},
"error": null
}
DefaultIsSet distinguishes a default someone chose from the shipped default of false.
Errors
Error response{
"status": "ERROR",
"request_id": null,
"result": null,
"error": {
"message": "<description>",
"reason": "KVM API ERROR"
}
}
REST API
| Endpoint type | DisplayNet API command |
|---|---|
| Address | POST /api/displaynet/<operation>, or name the operation in the body of a POST /api/displaynet. See Sending commands. |
| Role | User |
| Subcommand | Operation | Parameters |
|---|---|---|
workstation | kvm_workstation | action [args]* |
workstation_desk_add | kvm_workstation_desk_add | remote_id desks |
workstation_desk_clear | kvm_workstation_desk_clear | remote_id |
workstation_desk_list | kvm_workstation_desk_list | remote_id |
workstation_desk_remove | kvm_workstation_desk_remove | remote_id desks |
workstation_follow | kvm_workstation_follow | [target] [value] |
workstation_list | kvm_workstation_list | — |
workstation_multiview_add | kvm_workstation_multiview_add | remote_id configs |
workstation_multiview_clear | kvm_workstation_multiview_clear | remote_id |
workstation_multiview_list | kvm_workstation_multiview_list | remote_id |
workstation_multiview_remove | kvm_workstation_multiview_remove | remote_id configs |
workstation_show | kvm_workstation_show | remote_id |
A parameter in brackets is optional. A parameter marked * takes the remainder of the command line as one string. Pass the text exactly as you would type it on the TCI interface.
Every action except diagnose has a typed operation taking named fields, and a missing or unknown field is rejected before the command runs.
diagnose runs through kvm_workstation, which takes a raw grammar line: action and args, spelled as under Usage above.
See also
connect: the routing command thatfollowattaches to, and wherenokvm/withkvmare givenkvm hid: HID auto-connect, and the split-transmitter overridekvm config: the configuration a seat resolveskvm desk: multi-monitor seats
