Like the hardware, the software backend that orchestrates and drives all the individual hardware components of the platform, provides machine learning feedback when using the platform for optimization tasks in closed-loop processes, and serves as a human-machine-interface via an API was developed from scratch for this project. Several design considerations were taken into account when developing the software components and API. There are low-level modules that inherit from abstract base classes and take care of the hardware integration. These communicate with the hardware directly by sending hardware-specific commands via e.g. USB, serial ports, or vendorspecific APIs, depending on the automation interfaces exposed by the individual hardware components and devices. However, in general it is easier to not interact with these low-level modules directly, but rather use the high-level API we built on top of these, that also serves as the central orchestrator for scheduling and executing parallel, multi-threaded tasks on the hardware, and has several built-in heuristics, automations, error-corrections, and sanity-checks that are run before and while executing commands. The API defines a couple of very basic and easy to understand high-level instructions (such as adding a chemical, heating, sonicating, centrifuging, etc.) that are familiar to each chemist. When the user issues such a command, the backend will check the hardware configuration of all connected components, identify which components are needed for the requested action, put these into a priority queue of a task scheduler, subject the userdefined parameters to internal checks to ensure their feasibility and integrity, look up missing values (e.g., molar masses or densities of reactants that are needed for calculating the required amounts of that chemical in an addition step) from publicly available resources such as wiki data or pubchem , convert the units of quantities supplied by the user so that they match each other (e.g., µL into mL or even mol to mL), use heuristics to define the most sensible values for optional parameters that were not provided by the user, and once all checks are passed and all required components are available, start the execution of the requested step (see Figure ).