TypeScript SDK

The @rosfit/sdk package provides a type-safe client for interacting with the RosFit platform from any TypeScript or JavaScript environment — Node.js backends, React frontends, CLI tools, or serverless functions.

Installation

npm install @rosfit/sdk

Or with other package managers:

yarn add @rosfit/sdk
pnpm add @rosfit/sdk

The SDK requires Node.js 18+ or any modern browser with WebSocket support.

Authentication

Initialize the SDK with your API endpoint and an API key or JWT token:

import { RosFit } from '@rosfit/sdk'

const rosfit = new RosFit({
  baseUrl: 'http://localhost:8000/api/v1',
  apiKey: 'rft_live_a1b2c3d4e5f6',
})

// Or authenticate with email/password
const rosfit = new RosFit({
  baseUrl: 'http://localhost:8000/api/v1',
})

await rosfit.auth.login({
  email: '[email protected]',
  password: 'securepassword',
})

API keys can be generated from the dashboard under Settings > API Keys or via the REST API. Keys are scoped to specific roles (admin, operator, viewer) and can be revoked at any time.

RobotClient

The RobotClient provides a high-level interface for interacting with a single device.

Connecting to a device

const robot = rosfit.robot('dev_k8m2n4')

await robot.connect()
console.log('Connected to', robot.deviceId)

// Check connection status
console.log(robot.isConnected) // true

Subscribing to topics

// Subscribe to a specific telemetry topic
robot.subscribe('odom', (message) => {
  console.log('Position:', message.position)
  console.log('Orientation:', message.orientation)
})

// Subscribe to all telemetry
robot.subscribe('*', (topic, message) => {
  console.log(`[${topic}]`, message)
})

Publishing to topics

await robot.publish('cmd_vel', {
  linear: { x: 0.2, y: 0.0, z: 0.0 },
  angular: { x: 0.0, y: 0.0, z: 0.5 },
})

Sending commands

const result = await robot.sendCommand('navigate_to', {
  goal: {
    position: { x: 5.0, y: 3.0, z: 0.0 },
    orientation: { x: 0.0, y: 0.0, z: 0.0, w: 1.0 },
  },
}, { timeout: 120_000 })

console.log('Command status:', result.status) // 'acked'

Disconnecting

await robot.disconnect()

Fleet management

The Fleet class manages multiple devices at once.

Listing all robots

const fleet = rosfit.fleet()

const robots = await fleet.getAllRobots()
robots.forEach((r) => {
  console.log(`${r.name} [${r.status}] - ${r.type}`)
})

Getting a device by ID

const device = await fleet.getDeviceById('dev_k8m2n4')
console.log(device.name, device.status, device.lastSeen)

Grouping and filtering

// Group by type
const grouped = await fleet.groupBy('type')
console.log(grouped['ros2_robot'].length, 'ROS 2 robots')
console.log(grouped['micro_ros_mcu'].length, 'micro-ROS MCUs')

// Filter by status and group
const onlineWarehouse = await fleet.filter({
  status: 'online',
  group: 'warehouse-east',
  tags: ['amr'],
})

Telemetry

Live telemetry stream

const stream = rosfit.telemetry.subscribe('dev_k8m2n4', {
  topics: ['odom', 'battery_state', 'scan'],
  throttleMs: 100,
})

stream.on('data', (point) => {
  console.log(`[${point.topic}] ${point.timestamp}:`, point.data)
})

stream.on('error', (err) => console.error('Stream error:', err))

// Stop streaming
stream.unsubscribe()

Historical data query

const history = await rosfit.telemetry.query('dev_k8m2n4', {
  metric: 'battery_percent',
  from: new Date('2026-03-30T00:00:00Z'),
  to: new Date('2026-03-30T12:00:00Z'),
  interval: '5m',
})

history.data.forEach((point) => {
  console.log(`${point.time}: avg=${point.avg}, min=${point.min}, max=${point.max}`)
})

Commands

Send a command

const cmd = await rosfit.commands.send('dev_k8m2n4', {
  command: 'set_speed_limit',
  data: { max_linear: 0.5, max_angular: 1.0 },
  timeout: 30_000,
})

console.log('Command ID:', cmd.commandId)

Track command status

const status = await rosfit.commands.track(cmd.commandId)
console.log('Status:', status.status) // pending | delivered | acked | failed | expired
console.log('Result:', status.result)

Cancel a command

await rosfit.commands.cancel(cmd.commandId)

Broadcast to a group

const broadcast = await rosfit.commands.broadcast({
  group: 'warehouse-east',
  command: 'emergency_stop',
  data: {},
  priority: 'critical',
})

console.log(`Sent to ${broadcast.deviceCount} devices`)

Events

The SDK emits lifecycle events you can listen to globally or per-robot:

// Global events
rosfit.on('connect', (deviceId) => {
  console.log(`Device ${deviceId} connected`)
})

rosfit.on('disconnect', (deviceId, reason) => {
  console.log(`Device ${deviceId} disconnected: ${reason}`)
})

rosfit.on('error', (err) => {
  console.error('SDK error:', err.message)
})

// Per-robot events
const robot = rosfit.robot('dev_k8m2n4')

robot.on('telemetry', (topic, data) => {
  console.log(`Telemetry on ${topic}:`, data)
})

robot.on('command', (cmd) => {
  console.log(`Command ${cmd.id} status: ${cmd.status}`)
})

robot.on('shadowUpdate', (delta) => {
  console.log('Shadow delta received:', delta)
})
EventScopePayloadDescription
connectglobaldeviceIdA device connected to the broker
disconnectglobaldeviceId, reasonA device disconnected
errorglobalErrorSDK-level error
telemetryrobottopic, dataNew telemetry data received
commandrobotCommandResultCommand status update
shadowUpdaterobotdeltaShadow delta pushed from server