REST API Reference
The RosFit REST API exposes every platform capability — device management, telemetry queries, command dispatch, shadow state, and OTA firmware updates — through a consistent JSON API powered by FastAPI.
Base URL
All endpoints are relative to the API base URL:
http://localhost:8000/api/v1
For production deployments, replace localhost:8000 with your API host. All requests must include a Content-Type: application/json header for request bodies and an Authorization: Bearer <token> header for authenticated endpoints.
Authentication
POST /auth/register
Register a new user account.
curl -X POST http://localhost:8000/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "securepassword",
"name": "Fleet Admin",
"role": "admin"
}'
Response 201 Created
{
"id": "usr_a1b2c3",
"email": "[email protected]",
"name": "Fleet Admin",
"role": "admin",
"created_at": "2026-03-30T10:00:00Z"
}
POST /auth/login
Authenticate and receive a JWT token pair.
curl -X POST http://localhost:8000/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "securepassword"
}'
Response 200 OK
{
"access_token": "eyJhbGciOiJIUzI1NiIs...",
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
"token_type": "bearer",
"expires_in": 3600
}
POST /auth/refresh
Exchange a refresh token for a new access token.
| Parameter | Type | Description |
|---|---|---|
refresh_token | string | The refresh token from login |
GET /auth/me
Return the authenticated user's profile. Requires a valid Authorization: Bearer header.
POST /auth/devices/token
Generate an MQTT access token for a specific device. Used during device provisioning to create scoped credentials.
curl -X POST http://localhost:8000/api/v1/auth/devices/token \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"device_id": "bot-01",
"scopes": ["publish", "subscribe"],
"ttl_hours": 8760
}'
Response 200 OK
{
"device_id": "bot-01",
"mqtt_token": "mqtt_tok_x9y8z7w6",
"expires_at": "2027-03-30T10:00:00Z"
}
Devices
GET /devices
List all registered devices. Supports pagination and filtering.
| Query Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
per_page | integer | 50 | Items per page (max 200) |
status | string | — | Filter by device state (online, offline, error, etc.) |
type | string | — | Filter by device type (ros2_robot, micro_ros_mcu, etc.) |
group | string | — | Filter by group name |
tag | string | — | Filter by tag |
curl http://localhost:8000/api/v1/devices?status=online&type=ros2_robot \
-H "Authorization: Bearer <access_token>"
POST /devices
Register a new device and receive MQTT credentials.
curl -X POST http://localhost:8000/api/v1/devices \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "turtlebot-01",
"type": "ros2_robot",
"group": "warehouse-east",
"tags": ["amr", "navigation"],
"metadata": {
"ros_distro": "jazzy",
"firmware_version": "2.1.0",
"hardware": {
"model": "turtlebot3-waffle",
"serial_number": "TB3-2026-001"
}
}
}'
Response 201 Created
{
"device_id": "dev_k8m2n4",
"name": "turtlebot-01",
"type": "ros2_robot",
"status": "provisioning",
"group": "warehouse-east",
"tags": ["amr", "navigation"],
"access_token": "mqtt_tok_a1b2c3d4",
"mqtt_topics": {
"publish": "rosfit/dev_k8m2n4/#",
"subscribe": "rosfit/dev_k8m2n4/#"
},
"created_at": "2026-03-30T10:00:00Z"
}
GET /devices/{device_id}
Return full details for a single device including current status, metadata, and last-seen timestamp.
PUT /devices/{device_id}
Update a device's mutable fields (name, group, tags, metadata).
DELETE /devices/{device_id}
Decommission a device. Revokes MQTT credentials and sets the device state to decommissioned. This action is irreversible.
Telemetry
GET /telemetry/{device_id}
Return the latest telemetry snapshot for a device.
curl http://localhost:8000/api/v1/telemetry/dev_k8m2n4 \
-H "Authorization: Bearer <access_token>"
Response 200 OK
{
"device_id": "dev_k8m2n4",
"timestamp": "2026-03-30T10:05:32Z",
"data": {
"battery_percent": 78,
"cpu_temp": 52.3,
"odom": {
"position": { "x": 12.4, "y": 3.7, "z": 0.0 },
"orientation": { "x": 0.0, "y": 0.0, "z": 0.38, "w": 0.92 }
},
"velocity": {
"linear": { "x": 0.15, "y": 0.0, "z": 0.0 },
"angular": { "x": 0.0, "y": 0.0, "z": 0.02 }
}
}
}
GET /telemetry/{device_id}/history
Query historical telemetry from TimescaleDB. Returns time-bucketed aggregates.
| Query Parameter | Type | Default | Description |
|---|---|---|---|
metric | string | — | Metric name (e.g. battery_percent, cpu_temp, odom.position.x) |
from | ISO 8601 | 1 hour ago | Start of time range |
to | ISO 8601 | now | End of time range |
interval | string | 1m | Bucket interval (10s, 1m, 5m, 1h, 1d) |
curl "http://localhost:8000/api/v1/telemetry/dev_k8m2n4/history?metric=battery_percent&from=2026-03-30T00:00:00Z&to=2026-03-30T12:00:00Z&interval=5m" \
-H "Authorization: Bearer <access_token>"
Response 200 OK
{
"device_id": "dev_k8m2n4",
"metric": "battery_percent",
"interval": "5m",
"data": [
{ "time": "2026-03-30T00:00:00Z", "avg": 95.2, "min": 94.8, "max": 95.5 },
{ "time": "2026-03-30T00:05:00Z", "avg": 94.9, "min": 94.5, "max": 95.1 }
]
}
Commands
POST /commands/{device_id}
Send a command to a specific device.
curl -X POST http://localhost:8000/api/v1/commands/dev_k8m2n4 \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"command": "navigate_to",
"data": {
"goal": {
"position": { "x": 5.0, "y": 3.0, "z": 0.0 },
"orientation": { "x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0 }
},
"max_velocity": 0.5
},
"timeout_sec": 120
}'
Response 202 Accepted
{
"command_id": "cmd_p3q4r5",
"device_id": "dev_k8m2n4",
"command": "navigate_to",
"status": "pending",
"created_at": "2026-03-30T10:06:00Z"
}
GET /commands/{device_id}
List commands sent to a device. Supports ?status=pending|delivered|acked|failed|expired filtering.
GET /commands/{device_id}/{cmd_id}
Get the status and result of a specific command.
DELETE /commands/{device_id}/{cmd_id}
Cancel a pending or in-progress command.
POST /commands/$broadcast
Broadcast a command to all devices in a group.
curl -X POST http://localhost:8000/api/v1/commands/\$broadcast \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"group": "warehouse-east",
"command": "emergency_stop",
"data": {},
"priority": "critical"
}'
Device Shadow
The device shadow maintains a desired/reported state pair for each device, enabling offline configuration updates that sync when the device reconnects.
GET /shadows/{device_id}
Return the full shadow document including desired, reported, and metadata sections.
curl http://localhost:8000/api/v1/shadows/dev_k8m2n4 \
-H "Authorization: Bearer <access_token>"
Response 200 OK
{
"device_id": "dev_k8m2n4",
"version": 42,
"desired": {
"max_speed": 0.8,
"led_color": "green",
"firmware_version": "2.2.0"
},
"reported": {
"max_speed": 0.5,
"led_color": "green",
"firmware_version": "2.1.0"
},
"delta": {
"max_speed": 0.8,
"firmware_version": "2.2.0"
},
"metadata": {
"desired": { "max_speed": { "timestamp": "2026-03-30T10:00:00Z" } },
"reported": { "max_speed": { "timestamp": "2026-03-30T09:55:00Z" } }
}
}
PUT /shadows/{device_id}/desired
Update the desired state. The delta is computed automatically and pushed to the device via MQTT.
curl -X PUT http://localhost:8000/api/v1/shadows/dev_k8m2n4/desired \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"max_speed": 1.0,
"camera_resolution": "1080p"
}'
GET /shadows/{device_id}/delta
Return only the fields that differ between desired and reported state.
GET /shadows/{device_id}/history
Return a paginated history of shadow state changes.
OTA
POST /ota/firmware
Upload a new firmware binary. Send as multipart/form-data.
curl -X POST http://localhost:8000/api/v1/ota/firmware \
-H "Authorization: Bearer <access_token>" \
-F "[email protected]" \
-F "version=2.2.0" \
-F "device_type=ros2_robot" \
-F "changelog=Bug fixes and performance improvements"
GET /ota/firmware
List available firmware versions. Supports ?device_type= filtering.
POST /ota/deployments
Create a new OTA deployment targeting a device, group, or the entire fleet.
curl -X POST http://localhost:8000/api/v1/ota/deployments \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"firmware_version": "2.2.0",
"target": {
"type": "group",
"value": "warehouse-east"
},
"strategy": "rolling",
"max_concurrent": 5,
"rollback_on_failure": true
}'
GET /ota/deployments/{deploy_id}
Get the status of a deployment including per-device rollout progress.
POST /ota/rollback/{device_id}
Roll back a specific device to its previous firmware version.