This section summarizes version 1.7 of the INDI protocol. For the normative specification (message grammar, semantics, etc.), see the official INDI.pdf.
A client begins by asking device to describe itself. The client may request all devices, all properties of one device, or one specific property. Devices answer with definitions that fully describe each property and its elements.
Any device—or client—may subscribe to messages about other devices and properties by issuing getProperties with device and optional name. From that point, matching defXXX and setXXX traffic is mirrored to the requester, enabling coordination and higher-level behaviors.
Nyx mirrors INDI’s XML as JSON with a minimal, lossless mapping: the element name is stored under "<>", attributes use an "@" prefix, text content goes under "$", and child elements appear in a "children" array (order preserved). Values are strings by design; clients parse numbers where needed.
The schema below describes the message structures for both the INDI protocol and its Nyx overlay. Nyx-specific extensions are explicitly noted.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:simpleType name="propertyState">
<xs:restriction base="xs:token">
<xs:enumeration value="Idle"/>
<xs:enumeration value="Ok"/>
<xs:enumeration value="Busy"/>
<xs:enumeration value="Alert"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="propertyPerm">
<xs:restriction base="xs:token">
<xs:enumeration value="ro"/>
<xs:enumeration value="wo"/>
<xs:enumeration value="rw"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="switchRule">
<xs:restriction base="xs:token">
<xs:enumeration value="OneOfMany"/>
<xs:enumeration value="AtMostOne"/>
<xs:enumeration value="AnyOfMany"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="blobEnable">
<xs:restriction base="xs:token">
<xs:enumeration value="Never"/>
<xs:enumeration value="Also"/>
<xs:enumeration value="Only"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="streamEnable">
<xs:restriction base="xs:token">
<xs:enumeration value="Never"/>
<xs:enumeration value="Also"/>
<xs:enumeration value="Only"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="message">
<xs:complexType>
<xs:attribute name="device" type="xs:string" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="getProperties">
<xs:complexType>
<xs:attribute name="version" type="xs:string" use="required"/>
<xs:attribute name="device" type="xs:string" use="optional"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="delProperty">
<xs:complexType>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="enableBLOB">
<xs:complexType mixed="true">
<xs:attribute name="client" type="xs:string" use="optional"/>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="enableStream">
<xs:complexType mixed="true">
<xs:attribute name="client" type="xs:string" use="optional"/>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="defNumberVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="defNumber"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute name="group" type="xs:string" use="optional"/>
<xs:attribute name="hints" type="xs:string" use="optional"/>
<xs:attribute name="state" type="propertyState" use="required"/>
<xs:attribute name="perm" type="propertyPerm" use="required"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="defNumber">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute name="format" type="xs:string" use="required"/>
<xs:attribute name="min" type="xs:decimal" use="required"/>
<xs:attribute name="max" type="xs:decimal" use="required"/>
<xs:attribute name="step" type="xs:decimal" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="setNumberVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneNumber"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="state" type="propertyState" use="optional"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="newNumberVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneNumber"/>
</xs:sequence>
<xs:attribute name="client" type="xs:string" use="optional"/>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="oneNumber">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="defTextVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="defText"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute name="group" type="xs:string" use="optional"/>
<xs:attribute name="hints" type="xs:string" use="optional"/>
<xs:attribute name="state" type="propertyState" use="required"/>
<xs:attribute name="perm" type="propertyPerm" use="required"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="defText">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="setTextVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneText"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="state" type="propertyState" use="optional"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="newTextVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneText"/>
</xs:sequence>
<xs:attribute name="client" type="xs:string" use="optional"/>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="oneText">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="defLightVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="defLight"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute name="group" type="xs:string" use="optional"/>
<xs:attribute name="hints" type="xs:string" use="optional"/>
<xs:attribute name="state" type="propertyState" use="required"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="defLight">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="setLightVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneLight"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="state" type="propertyState" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="oneLight">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="defSwitchVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="defSwitch"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute name="group" type="xs:string" use="optional"/>
<xs:attribute name="hints" type="xs:string" use="optional"/>
<xs:attribute name="state" type="propertyState" use="required"/>
<xs:attribute name="perm" type="propertyPerm" use="required"/>
<xs:attribute name="rule" type="switchRule" use="required"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="defSwitch">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="setSwitchVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneSwitch"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="state" type="propertyState" use="optional"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="newSwitchVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneSwitch"/>
</xs:sequence>
<xs:attribute name="client" type="xs:string" use="optional"/>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="oneSwitch">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="defBLOBVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="defBLOB"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute name="group" type="xs:string" use="optional"/>
<xs:attribute name="hints" type="xs:string" use="optional"/>
<xs:attribute name="state" type="propertyState" use="required"/>
<xs:attribute name="perm" type="propertyPerm" use="required"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="defBLOB">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute name="format" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="setBLOBVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneBLOB"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="state" type="propertyState" use="optional"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="newBLOBVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneBLOB"/>
</xs:sequence>
<xs:attribute name="client" type="xs:string" use="optional"/>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="oneBLOB">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="size" type="xs:decimal" use="required"/>
<xs:attribute name="format" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="defStreamVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="defStream"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
<xs:attribute name="group" type="xs:string" use="optional"/>
<xs:attribute name="hints" type="xs:string" use="optional"/>
<xs:attribute name="state" type="propertyState" use="required"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="defStream">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="label" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="setStreamVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneStream"/>
</xs:sequence>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="state" type="propertyState" use="optional"/>
<xs:attribute name="timeout" type="xs:decimal" use="optional"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
<xs:attribute name="message" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="newStreamVector">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="oneStream"/>
</xs:sequence>
<xs:attribute name="client" type="xs:string" use="optional"/>
<xs:attribute name="device" type="xs:string" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="timestamp" type="xs:dateTime" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="oneStream">
<xs:complexType mixed="true">
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>