Skip to content

Type Definitions

Complete type reference for the Urban Sky SDK interfaces and types. Everything on this page mirrors the exported types in sdk/js/src/index.ts (Python equivalents live in sdk/py/src/urbansky_sdk/__init__.py).

Configuration

SDKConfig

Configuration object for initializing the SDK.

typescript
interface SDKConfig {
  apiToken: string // Required: your Urban Sky API token
  baseUrl?: string // Optional: API base URL (defaults to production)
  debug?: boolean // Optional: enable debug logging (default false)
}

Defaults:

typescript
const DEFAULT_CONFIG: Partial<SDKConfig> = {
  baseUrl: 'https://api.ops.atmosys.com',
  debug: false,
}

These three fields are the entire configuration surface — reconnection and heartbeat behavior is handled internally by the Centrifugo client and is not configurable.

Core Types

BalloonUpdate

Main data structure for balloon telemetry updates.

typescript
interface BalloonUpdate {
  balloonId: string // Unique balloon identifier
  missionId: string // Associated mission ID
  devices: DeviceLocation[] // Array of device telemetry data
}

UnassignedDevicesUpdate

Real-time telemetry for devices not assigned to any mission.

typescript
interface UnassignedDevicesUpdate {
  devices: DeviceLocation[]
}

DeviceLocation

Individual device telemetry within a balloon or unassigned-devices update.

typescript
interface DeviceLocation {
  deviceId: string // Unique device identifier (MAC address)
  deviceType: string // Raw device type string as reported by the device (e.g. "PLD", "APX", "BLS")
  lat: number // Latitude (decimal degrees)
  lng: number // Longitude (decimal degrees)
  altitude?: number // Altitude in meters
  timestamp: string // ISO 8601 timestamp
  batteryInfo?: BatteryInfo | null
  environmental?: EnvironmentalInfo | null
  status?: StatusInfo | null
  motion?: MotionInfo | null
  internal?: InternalTelemetry // Extended fields (internal_testing orgs only)
}

BatteryInfo / EnvironmentalInfo / StatusInfo / MotionInfo

typescript
interface BatteryInfo {
  soc?: number | null // State of charge (%)
  voltage?: number | null // Battery voltage (V)
  temperature?: number | null // Battery temperature (°C)
  power?: number | null // Battery power (W)
}

interface EnvironmentalInfo {
  airTemperature?: number | null // Air temperature (°C)
  pressure?: number | null // Atmospheric pressure (mBar)
  humidity?: number | null // Relative humidity (%)
}

interface StatusInfo {
  systemStatus?: string | number | null
  flightStage?: string | null // UPPERCASE stage, see FlightStage below
  gpsFixStatus?: number | null
  connectionStrength?: number | null // RSSI or signal strength
}

interface MotionInfo {
  ascentRate?: number | null
  groundSpeed?: number | null
  heading?: number | null
}

InternalTelemetry

Extended telemetry fields available only to organizations with internal_testing enabled. See Internal Telemetry Guide for details.

typescript
interface InternalTelemetry {
  ack?: boolean // Device acknowledged last command
  batteryVoltage?: number // Battery voltage (V)
  batterySoc?: number // Battery state of charge (%)
  batteryTemp?: number // Battery temperature (°C)
  tempBoard?: number // Board temperature (°C)
  airTemp?: number // External air temperature (°C)
  batteryHeating?: boolean // Battery heater active
  firmwareVersion?: string // Running firmware version
  hardwareVersion?: string // Hardware version
  flightStage?: string // PREFLIGHT | ASCENT | FLOAT | DESCENT | GROUNDED
  geofenceActive?: boolean // Geofence currently active
  geofenceBroken?: boolean // Geofence boundary violated
  gpsFixStatus?: number // GPS fix type
  gpsSatellites?: number // Satellites in view
  ascentRate?: number // Ascent rate (m/s)
  uptime?: number // System uptime (ms)
  massDropped?: number // Ballast dropped (g, ballaster only)
  dispenserIsDropping?: boolean // Dispenser active (ballaster only)
  systemStatusFlag?: boolean // system_status flag (unpacked from bitmask)
  gpsFixFlag?: boolean // gps_fix_status flag (unpacked from bitmask)
}

FlightStage values

StatusInfo.flightStage is typed as string | null — the SDK does not export a FlightStage type or a FLIGHT_STAGES constants object. On the wire it is always one of these UPPERCASE values:

'PREFLIGHT' | 'ASCENT' | 'FLOAT' | 'DESCENT' | 'GROUNDED'

Compare flightStage against these string values directly; there is no exported type or constants object to import.

ConnectionState

Represents the current connection state.

typescript
interface ConnectionState {
  state: 'connected' | 'connecting' | 'disconnected' | 'failed'
  reason?: string // Error reason if state is "failed"
}

SDKTokenResponse

Response from the /sdk/token exchange performed during init().

typescript
interface SDKTokenResponse {
  token: string // Short-lived connection token (grants no channel access on its own)
  subscriptionToken?: string // Authorizes subscription to `channelName` only
  orgId: string // Your organization ID
  sdkVersion: string // Server-selected SDK version
  channelName?: string // Org-scoped channel the SDK subscribes to
  websocketUrl?: string // Public Centrifugo WebSocket URL
}

The SDK consumes all of these automatically — you never pass them yourself. In particular, websocketUrl is how the SDK resolves the realtime host, so there is no need to construct or override a WebSocket URL. baseUrl in SDKConfig is the REST API only.

Event Types

SDKEventType

Available event types you can listen for.

typescript
type SDKEventType =
  | 'balloon:update' // Balloon telemetry updates (mission-assigned devices)
  | 'unassigned:devices' // Unassigned device updates (devices not assigned to missions)
  | 'connected' // Successfully connected
  | 'disconnected' // Disconnected from service
  | 'connecting' // Attempting to connect
  | 'failed' // Connection failed
  | 'error' // General error occurred

SDKEventHandler

Generic event handler function type.

typescript
type SDKEventHandler<T = unknown> = (data: T) => void

Error Types

All request failures throw a subclass of SdkError (note the casing — there is no SDKError class and no string code field).

typescript
class ValidationError extends Error {} // Client-side input validation failed

class SdkError extends Error {
  statusCode?: number // HTTP status of the failed request, when available
  responseData?: string // Raw response body, when available
}

class SdkAuthenticationError extends SdkError {} // statusCode 401 (or 403 responses)
class SdkNotFoundError extends SdkError {} // statusCode 404
class SdkBadRequestError extends SdkError {} // statusCode 400
class SdkNetworkError extends SdkError {} // No response — responseData carries the underlying error message

Handling pattern:

typescript
import { SdkAuthenticationError, SdkNotFoundError, SdkError } from '@urbansky/sdk-js'

try {
  await sdk.listMissions()
} catch (err) {
  if (err instanceof SdkAuthenticationError) {
    // Refresh/rotate the API token
  } else if (err instanceof SdkNotFoundError) {
    // Resource does not exist
  } else if (err instanceof SdkError) {
    console.error(err.statusCode, err.responseData)
  }
}

Python Type Equivalents

The Python SDK (urbansky_sdk) mirrors these types as dataclasses with snake_case fields, and uses the same error class names:

python
from urbansky_sdk import (
    SDKConfig,          # api_token, base_url
    BalloonUpdate,      # balloon_id, mission_id, devices
    DeviceLocation,     # device_id, device_type, lat, lng, altitude, timestamp, ...
    ConnectionState,
    SDKEventType,
    ValidationError,
    SdkError,           # .status_code, .response_data
    SdkAuthenticationError,
    SdkNotFoundError,
    SdkBadRequestError,
    SdkNetworkError,
)

Data Flow

Mission-Assigned Devices (Balloon Updates)

  1. Device sends telemetry data
  2. Data is assigned to a mission based on device assignment
  3. Data is batched by mission/balloon
  4. balloon:update events are emitted with all devices in the mission

Unassigned Devices

  1. Device sends telemetry data
  2. Device has no mission assignment
  3. Data is cached by organization
  4. unassigned:devices events are emitted with all unassigned devices in the organization

Usage Patterns

Handle Both Event Types

typescript
const sdk = await UrbanSkySDK.init({ apiToken: 'your-token' })

// Handle mission-assigned devices
sdk.on('balloon:update', (update: BalloonUpdate) => {
  console.log(`Mission ${update.missionId} has ${update.devices.length} devices`)
})

// Handle unassigned devices
sdk.on('unassigned:devices', (update: UnassignedDevicesUpdate) => {
  console.log(`${update.devices.length} unassigned devices detected`)
})

// Connection state handlers
sdk.on('connected', (state: ConnectionState) => {})
sdk.on('disconnected', (state: ConnectionState) => {})
sdk.on('failed', (state: ConnectionState) => {})

// Error handler
sdk.on('error', (error: { message: string; error?: string }) => {})

Related Documentation: