REST API (PolyscopeX)
Remote send commands to the robot via the REST API protocol (PolyscopeX only).
The REST API provides a modern HTTP-based interface for controlling PolyscopeX robots. It replaces the legacy Dashboard Server on new UR controllers.
Quick Start
using UnderAutomation.UniversalRobots;var robot = new UR();// Connect with REST API enabledrobot.Connect(new ConnectParameters("192.168.0.1"){Rest = { Enable = true }});// Control the robotrobot.Rest.PowerOn();robot.Rest.BrakeRelease();robot.Rest.LoadProgram("my_program");robot.Rest.Play();// Get program statevar state = robot.Rest.GetProgramState();Console.WriteLine($"State: {state.Value.State}"); // Playing, Stopped, Paused
Standalone Client
Use RestClient independently from the main UR class:
using UnderAutomation.UniversalRobots.Rest;var client = new RestClient();client.Enable("192.168.0.1");client.PowerOn();client.LoadProgram("my_program");client.Play();client.Disable();
Enable Remote Mode
Your robot must be in Remote mode to accept commands. Toggle the switch at the top right of PolyscopeX:

Connection Parameters
Configure the REST client via RestConnectParameters:
| Property | Type | Default | Description |
|---|---|---|---|
Enable | bool | false | Enable REST API client |
Port | int | 80 | HTTP port |
Version | RestApiVersion | Latest | API version (V1, Latest) |
TimeoutMs | int | 5000 | Request timeout in milliseconds |
robot.Connect(new ConnectParameters("192.168.0.1"){Rest ={Enable = true,Port = 80,Version = RestApiVersion.V1,TimeoutMs = 10000}});
Robot State Control
Control the robot's operational state:
PowerOn
Power on the robot.
RestApiResponse response = robot.Rest.PowerOn();if (response.Succeed)Console.WriteLine("Robot powered on");
PowerOff
Power off the robot.
robot.Rest.PowerOff();
BrakeRelease
Release the robot brakes after powering on.
robot.Rest.PowerOn();robot.Rest.BrakeRelease();
UnlockProtectiveStop
Unlock the robot from a protective stop state.
robot.Rest.UnlockProtectiveStop();
RestartSafety
Restart the safety system.
robot.Rest.RestartSafety();
ChangeRobotState
Generic method to change robot state:
robot.Rest.ChangeRobotState(RobotStateAction.POWER_ON);robot.Rest.ChangeRobotState(RobotStateAction.BRAKE_RELEASE);
Available actions:
RobotStateAction.POWER_ONRobotStateAction.POWER_OFFRobotStateAction.BRAKE_RELEASERobotStateAction.UNLOCK_PROTECTIVE_STOPRobotStateAction.RESTART_SAFETY
Program Control
Control program execution:
LoadProgram
Load a program by name. The .urp extension is optional.
robot.Rest.LoadProgram("my_program");// orrobot.Rest.LoadProgram("my_program.urp");
Play
Start playing the loaded program.
robot.Rest.Play();
Pause
Pause the running program.
robot.Rest.Pause();
Stop
Stop the running program.
robot.Rest.Stop();
Resume
Resume a paused program.
robot.Rest.Resume();
GetProgramState
Get the current program state.
RestApiResponse<ProgramStateResponse> response = robot.Rest.GetProgramState();if (response.Succeed){RestProgramState state = response.Value.State;// state: Playing, Stopped, Paused, Unknown}
ChangeProgramState
Generic method to change program state:
robot.Rest.ChangeProgramState(ProgramStateAction.play);robot.Rest.ChangeProgramState(ProgramStateAction.stop);
Available actions:
ProgramStateAction.playProgramStateAction.pauseProgramStateAction.stopProgramStateAction.resume
Response Handling
All methods return RestApiResponse or RestApiResponse<T>:
RestApiResponse response = robot.Rest.PowerOn();// Check successif (response.Succeed){Console.WriteLine("Success");}else{Console.WriteLine($"Error: {response.Message}");Console.WriteLine($"HTTP Status: {response.StatusCode}");Console.WriteLine($"Raw response: {response.RawResponse}");}
| Property | Type | Description |
|---|---|---|
Succeed | bool | true if HTTP 200 OK |
StatusCode | HttpStatusCode | HTTP status code |
Message | string | Success message or error description |
RawResponse | string | Raw JSON response body |
Value | T | Typed response value (generic version only) |
Error Handling
Handle errors using the InternalErrorOccured event:
robot.Rest.InternalErrorOccured += (sender, e) =>{Console.WriteLine($"REST API Error: {e.Message}");Console.WriteLine($"Exception: {e.Exception}");};
API Endpoints
The SDK maps to these PolyscopeX REST API endpoints:
| Method | SDK Method | Endpoint |
|---|---|---|
| PUT | ChangeRobotState() | /universal-robots/robot-api/robotstate/v1/state |
| PUT | LoadProgram() | /universal-robots/robot-api/program/v1/load |
| PUT | ChangeProgramState() | /universal-robots/robot-api/program/v1/state |
| GET | GetProgramState() | /universal-robots/robot-api/program/v1/state |
Migration from Dashboard Server
Migrating from legacy Dashboard Server to REST API:
// Dashboard Server (CB-series / e-Series)robot.Connect(new ConnectParameters("192.168.0.1"){Dashboard = { Enable = true }});robot.Dashboard.PowerOn();robot.Dashboard.LoadProgram("/programs/my_program.urp");robot.Dashboard.Play();// REST API (PolyscopeX)robot.Connect(new ConnectParameters("192.168.0.1"){Rest = { Enable = true }});robot.Rest.PowerOn();robot.Rest.LoadProgram("my_program");robot.Rest.Play();
Key differences:
- REST API uses HTTP (port 80) instead of TCP socket (port 29999)
- Program names don't require full path
- REST API returns structured
RestApiResponseobjects
Properties
| Property | Type | Description |
|---|---|---|
IP | string | Robot IP address |
Port | int | HTTP port |
Version | RestApiVersion | API version |
TimeoutMs | int | Request timeout |
Initialized | bool | true if client is enabled |
if (robot.Rest.Initialized){Console.WriteLine($"Connected to {robot.Rest.IP}:{robot.Rest.Port}");}