Chapter 5: Phase 2 - API Interface Design

弘益人間 (Hongik Ingan) · Benefit All Humanity

5.1 Purpose of Phase 2

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.

5.2 Base URL and Versioning

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).

5.3 Authentication

Obtaining a Token

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
}

Using the Token

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.

5.4 Core Endpoints

Section 4 of the specification defines the following core endpoints. All paths are relative to the base URL (/api/v1).

MethodPathFunction
GET/robot/statusGet robot status
POST/robot/cleanStart cleaning
POST/robot/stopStop cleaning
POST/robot/dockReturn 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=0Get cleaning history
POST/robot/scheduleCreate cleaning schedule

Robot Status

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.

Start Cleaning

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.

Stop Cleaning and Return to Dock

POST /robot/stop
Response: { "status": "stopped", "sessionId": "UUID", "areaCleaned": "float (m²)" }

POST /robot/dock
Response: { "status": "returning", "distance": "float (meters)", "estimatedTime": "integer (seconds)" }

Get Map and Update Rooms

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" }

Cleaning History and Schedules

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" }

5.5 WebSocket API

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" }
}

5.6 Error Handling

Error responses use the following format.

{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human readable message",
    "details": {},
    "timestamp": "ISO8601 datetime"
  }
}
Error codeMeaning
ROBOT_BUSYThe robot is already cleaning
LOW_BATTERYThe battery is too low for the operation
INVALID_COMMANDThe command parameters are invalid
NOT_CONNECTEDThe robot is not connected to the network
SENSOR_ERRORA sensor malfunction was detected
NAVIGATION_ERRORThe robot is unable to navigate
DOCK_NOT_FOUNDThe 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.

5.7 Rate Limiting

5.8 Pagination and Filtering

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.

5.9 Batch Operations and Additional Features

Batch Operations

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": {}} ] }

Monitoring and Advanced Features

EndpointFunction
GET /robot/metricsCPU and memory usage, temperature, network traffic, uptime
POST /robot/control/joystickRemote manual control (linear velocity m/s, angular velocity rad/s)
GET /robot/camera/streamMJPEG camera stream
GET /robot/map/export?format=png|svg|jsonMap 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.

5.10 Calling the API with the Reference SDK

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

Key Takeaways

Review Questions

  1. Describe the base URL of the Phase 2 API and how the version is indicated.
  2. Explain how a JWT access token is obtained and used.
  3. Write a POST /robot/clean body that asks the robot to clean only the living room and kitchen at power level 60.
  4. What is the REST API suited to, and what is the WebSocket API suited to?
  5. Name three of the seven standard error codes and explain their meaning.
  6. What response does a client receive when it exceeds the rate limit?
  7. In what situations is the batch endpoint useful?

📐 Simulator Panel 4