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.

ParameterTypeDescription
refresh_tokenstringThe 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 ParameterTypeDefaultDescription
pageinteger1Page number
per_pageinteger50Items per page (max 200)
statusstringFilter by device state (online, offline, error, etc.)
typestringFilter by device type (ros2_robot, micro_ros_mcu, etc.)
groupstringFilter by group name
tagstringFilter 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 ParameterTypeDefaultDescription
metricstringMetric name (e.g. battery_percent, cpu_temp, odom.position.x)
fromISO 86011 hour agoStart of time range
toISO 8601nowEnd of time range
intervalstring1mBucket 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.