The Phase 2 specification (PHASE-2-API, v1.0.0) defines the RESTful HTTP API and WebSocket interface for controlling and monitoring cleaning robots. It states that all endpoints MUST implement authentication and rate limiting. The data exchanged over the API uses the Phase 1 formats from Chapter 4 (RobotState, OccupancyGrid, CleaningSession and so on) unchanged.
The API is served by the robot itself (or a gateway acting for it). The base URL is shown below; the default port is 8080.
http://{robot_ip}:{port}/api/v1
The API version is part of the URL path (/api/v1/), and breaking changes require a new version number. The specification writes the base URL with http, but Phase 3 requires TLS 1.3 for all network communication, so real deployments must use HTTPS (see Chapter 6).
The client sends a username and password to POST /auth/token and receives a JWT access token and a refresh token. The lifetime of the access token is given in expires_in (seconds); the specification's example is 3600 seconds (one hour).
POST /auth/token
Content-Type: application/json
{
"username": "string",
"password": "string"
}
Response:
{
"access_token": "JWT token",
"refresh_token": "string",
"expires_in": 3600
}
Every subsequent request carries the Bearer token in the Authorization header.
Authorization: Bearer {access_token}
The Phase 3 specification allows JWT (recommended), OAuth 2.0 and, for simple integrations, API keys. OAuth 2.0 (RFC 6749) is the appropriate choice when a third-party service accesses the robot on a user's behalf.
Section 4 of the specification defines the following core endpoints. All paths are relative to the base URL (/api/v1).
| Method | Path | Function |
|---|---|---|
| GET | /robot/status | Get robot status |
| POST | /robot/clean | Start cleaning |
| POST | /robot/stop | Stop cleaning |
| POST | /robot/dock | Return to dock |
| GET | /robot/map?floor={floor_number} | Get map |
| PUT | /robot/map/rooms/{room_id} | Update room information |
| GET | /robot/history?limit=10&offset=0 | Get cleaning history |
| POST | /robot/schedule | Create cleaning schedule |
GET /robot/status
Response:
{
"robotId": "string",
"state": "RobotState object",
"uptime": "integer (seconds)",
"lastUpdate": "ISO8601 datetime"
}
The state in the response is the RobotState document from Chapter 4.
POST /robot/clean
Content-Type: application/json
{
"mode": "auto|spot|edge|custom",
"rooms": ["room_id1", "room_id2"],
"powerLevel": 0-100,
"waterLevel": 0-100
}
Response:
{
"sessionId": "UUID",
"status": "started",
"estimatedDuration": "integer (seconds)"
}
The sessionId in the response identifies the CleaningSession for this run. To clean only certain rooms, put their map room IDs in rooms.
POST /robot/stop
Response: { "status": "stopped", "sessionId": "UUID", "areaCleaned": "float (m²)" }
POST /robot/dock
Response: { "status": "returning", "distance": "float (meters)", "estimatedTime": "integer (seconds)" }
GET /robot/map?floor={floor_number}
Response: { "map": "OccupancyGrid object", "lastUpdated": "ISO8601 datetime" }
PUT /robot/map/rooms/{room_id}
Content-Type: application/json
{
"name": "Living Room",
"surfaceType": "hardwood",
"cleaningPriority": 1-10
}
Response: { "status": "updated", "room": "Room object" }
GET /robot/history?limit=10&offset=0
Response: { "sessions": ["CleaningSession", "array"], "total": "integer", "hasMore": "boolean" }
POST /robot/schedule
Content-Type: application/json
{
"enabled": true,
"schedule": [
{ "day": "monday|tuesday|...", "time": "HH:MM", "mode": "auto", "rooms": ["array (optional)"] }
]
}
Response: { "scheduleId": "UUID", "status": "created" }
Real-time state changes are delivered over WebSocket. The connection address is ws://{robot_ip}:{port}/ws; real deployments use WSS with TLS. Every message has a type (type) and a channel (channel).
{
"type": "subscribe|unsubscribe|command|event",
"channel": "status|sensors|map|logs",
"data": {}
}
When a client subscribes to the status channel at a 1000 ms interval, the robot reports changes with event messages.
// Subscription request
{ "type": "subscribe", "channel": "status", "interval": 1000 }
// Real-time event
{
"type": "event",
"channel": "status",
"timestamp": "ISO8601",
"data": { "battery": 75, "position": {"x": 2.5, "y": 3.1}, "mode": "cleaning" }
}
Error responses use the following format.
{
"error": {
"code": "ERROR_CODE",
"message": "Human readable message",
"details": {},
"timestamp": "ISO8601 datetime"
}
}
| Error code | Meaning |
|---|---|
ROBOT_BUSY | The robot is already cleaning |
LOW_BATTERY | The battery is too low for the operation |
INVALID_COMMAND | The command parameters are invalid |
NOT_CONNECTED | The robot is not connected to the network |
SENSOR_ERROR | A sensor malfunction was detected |
NAVIGATION_ERROR | The robot is unable to navigate |
DOCK_NOT_FOUND | The charging dock cannot be located |
Annex B of the specification lists RFC 9457 (Problem Details), the international standard for HTTP API error representation, among its referenced standards. Implementations should document how the error format above maps onto RFC 9457.
Every endpoint that returns a list supports standard pagination parameters.
GET /robot/history?limit=20&offset=40&sort=startTime&order=desc - limit: items per page (default 10, maximum 100) - offset: number of items to skip - sort: field to sort by - order: asc or desc
The specification gives GET /robot/history?mode=auto&minDuration=300, GET /robot/map/rooms?surfaceType=carpet and GET /robot/events?level=error&category=navigation as filter examples.
POST /robot/batch sends several requests at once and returns an array of results in request order.
POST /robot/batch
{
"operations": [
{ "method": "POST", "path": "/robot/clean", "body": {"mode": "spot"} },
{ "method": "PUT", "path": "/robot/config", "body": {"language": "ko"} }
]
}
Response:
{ "results": [ {"status": 200, "data": {}}, {"status": 200, "data": {}} ] }
| Endpoint | Function |
|---|---|
GET /robot/metrics | CPU and memory usage, temperature, network traffic, uptime |
POST /robot/control/joystick | Remote manual control (linear velocity m/s, angular velocity rad/s) |
GET /robot/camera/stream | MJPEG camera stream |
GET /robot/map/export?format=png|svg|json | Map export |
Because the camera stream and remote control directly affect privacy and safety, they should be available only to authenticated users, and users should be able to tell when they are in use.
The TypeScript SDK skeleton in the WIA public repository (cleaning-robot/api/typescript) provides a WiaCleaningRobot class that wraps these endpoints. The SDK is not published to public package registries, so obtain it directly from the repository (see section 3.9 of Chapter 3).
import { WiaCleaningRobot } from 'wia-rob-011';
const robot = new WiaCleaningRobot({
host: '192.168.1.100',
token: 'your_token_here'
});
await robot.connect(); // GET /health
const status = await robot.getStatus(); // GET /robot/status
await robot.startCleaning({ mode: 'auto' }); // POST /robot/clean
http://{robot_ip}:{port}/api/v1 with default port 8080; real deployments use HTTPSPOST /auth/token and sends it in a Bearer header/robot/status, /robot/clean, /robot/stop, /robot/dock, /robot/map, /robot/history and /robot/schedule/ws to the status, sensors, map and logs channelserror.code and seven standard error codesPOST /robot/clean body that asks the robot to clean only the living room and kitchen at power level 60.