For many complex experiments the bottleneck can be the capabilities of the microscope control software and the types of experiments it allows to conduct. With smart microscopy, one needs a dynamic feedback loop to control the microscope operation and the conditions based on the specific requirements of the experiment. This loop typically consists of three parts:
- monitoring
- analysis
- feedback
Luxendo light-sheet microscopes offer an open Application Programming Interface (API) that allows flexible scripting and smart microscopy implementation for a multitude of experiment types, such as sample tracking, sample finding or event detection.
The API is built on the MQTT publish-subscribe based messaging protocol, allowing third-party applications to monitor the microscope state and issue commands to the microscope. The commands are human-readable, JSON-formatted messages, that can be used to control all settings of the microscope and the experiment flow. These messages can be constructed and sent from any programming language that supports MQTT, such as Python, Java, LabView, Rust or JavaScript.
The Luxendo microscopes can be fully scripted by connecting to a Message Queuing Telemetry Transport (MQTT) broker on the image-acquisition PC. The API is based on JSON messages and is described in this document.
MQTT is a publisher/subscriber network protocol to deliver messages between devices. Each component publishes its state as a JSON message under its own topic, and in turn it subscribes to the topics of components from which it needs information.
Any programming language that has an MQTT client implementation can be used to interface with the microscope.
The topics are in the form of path/to/topic, where slashes separate multiple levels. These levels go in order of least specific to most specific.
To separate multiple microscopes on the network, every message has a root topic representing the hexadecimal serial number (SN) of the microscope, for example 01E3F023.
Each component has its own topic, and further optional subtopics. For example, the embedded system (that controls the microscope) would publish the stage-related messages to the topic SN/embedded/stages.
One can subscribe to multiple topics by using wildcards (#). Adding a # as the last level would subscribe to all subtopics. To see all messages of all components, one needs to subscribe to SN/#.
LuxLogger is a web-based tool to monitor and debug the MQTT communication. It can be used to subscribe to any topic, and to send any JSON message to any topic. This makes it useful for debugging applications connecting to the Luxendo API.
LuxLogger is included with all Luxendo microscopes, and supports all modern browsers.
The messages described below are just examples, and the real messages could differ. Always verify the actual messages with LuxLogger before using them from your application.
A few examples are shown below. When the message is published by the client, the heading will be “Client”. Conversely, when the message is published by the microscope, the heading will be “Microscope”.
Each JSON message has the following keys:
$.type: defines the message type, possible options:device,operation,network- Messages with
"type": "device"refer to the actual physical devices the microscope comprises of - Messages with
"type": "operation"refer to the microscope operation, e.g. stacks, channels - Messages with
"type": "network"refer to network related events, such as connection loss
- Messages with
$.data.device: type of device, dependent on the message type$.data.command: command dependent on device
The microscope typically publishes messages on a state change, and the command will be set.
The client can query the state of a device or operation with the get command. Other commands are device specific and are described below.
One of the first commands an application would typically send to the microscope is “Get Capabilities Request” message.
| Topic | SN/gui |
|---|---|
| Triggers | Get Capabilities Response |
| Schema File | /toMicroscope/capabilitiesToMicroscope.schema.json |
Example:
This message requests the microscope to publish its capabilities.
The capabilities response
| Topic | SN/embedded/system |
|---|---|
| Triggered by | Get Capabilities Request |
| Schema File | /fromMicroscope/capabilitiesFromMicroscope.schema.json |
{
"type": "operation",
"data": {
"device": "system",
"command": "devicestatus",
"scopetype": "MuVi-SPIM",
"capabilities": [
"stage",
"lasers",
"filterwheels",
"scanners",
"timings",
// other capabilities clipped
]
}
}The “scopetype” contains the type of the microscope. This is just for convenience, and the API behavior does not depend on the microscope type. The user interface uses this information to show microscope-specific graphics.
The “capabilities” array contains a list of strings listing the microscope’s modules – some of which can be configured using JSON messages. Only devices listed here are present in the microscope and can be controlled through the API.
This document was written by
- Balint Balazs, Senior Software Architect at Luxendo
- Jan Roden, Senior Software Architect at Luxendo
Feedback can be sent to software.luxendo@bruker.com
This work © 2025 by Luxendo GmbH is licensed under CC BY-SA 4.0



{ "type": "operation", "data": { "device": "system", "command": "scopeconfig" } }