REST for integration, raw MAVLink WebSocket for real-time data, versioned MQTT topics for remote relay and a Python SDK for drivers and extensions. This section defines target ports, endpoints, permissions and examples of KairOS’s own interface.
APIs and SDKs are described as a KairOS target contract; a stable version and compatibility guarantees have not yet been released.
KairOS repository ↗On this page +
Eight core endpoints
The control surface listens on port 8080 and returns JSON. Most requests require the X-KairOS-Key header. Each key has a permission level, allowing telemetry reads to be separated from flight commands, mission uploads and administrative operations.
| Method | Endpoint | Data or action |
|---|---|---|
| GET | /api/status | Health, uptime, FC connection, role, agent version |
| GET | /api/telemetry | Attitude, GPS, battery, RC channels, flight mode |
| GET | /api/params | FC parameter cache with prefix filtering |
| POST | /api/commands | Takeoff, land, goto, RTL, arm, disarm |
| GET | /api/config | Current agent configuration as JSON |
| PUT | /api/config | Change keys and hot-reload affected services |
| GET | /api/services | running, stopped or failed for managed services |
| GET | /api/logs | Structured events with service and level filters |
curl -s http://<board-ip>:8080/api/telemetry \
-H "X-KairOS-Key: <your-key>" | jq{
"armed": true,
"mode": "GUIDED",
"battery": { "voltage": 22.4, "pct": 78 },
"gps": { "fix": 3, "satellites": 14, "alt": 50.2 },
"attitude": { "roll": 0.02, "pitch": -0.01, "yaw": 182.5 }
}Read telemetry and send a command from Python
import httpx
BASE = "http://<board-ip>:8080"
headers = {"X-KairOS-Key": "<your-key>"}
telem = httpx.get(f"{BASE}/api/telemetry", headers=headers).json()
print(telem["battery"]["pct"], telem["gps"]["satellites"])
httpx.post(
f"{BASE}/api/commands",
headers=headers,
json={"command": "takeoff", "params": {"alt": 10}},
)One MAVLink stream, multiple transports
| Surface | Port or topic | Purpose |
|---|---|---|
| REST | :8080 | Status, telemetry, configuration, services, commands |
| MAVLink WebSocket | :8765 | Bidirectional binary MAVLink v2 |
| WebRTC WHEP | :8889 | Local video |
| Status | kairos/v1/agents/{agent_id}/status | Retained health and agent availability |
| Telemetry | kairos/v1/agents/{agent_id}/telemetry | Vehicle state stream |
| Events | kairos/v1/agents/{agent_id}/events | Observable events and warnings |
| Commands | kairos/v1/agents/{agent_id}/commands | Commands to the agent with QoS 1 |
| ACK | kairos/v1/agents/{agent_id}/acks/{command_id} | Result of a specific command |
| WebRTC signaling | kairos/v1/agents/{agent_id}/video/webrtc/offer | SDP offer for P2P video |
The router receives one stream from the FC and distributes it to multiple consumers simultaneously: browser GCS over WebSocket 8765, SITL/engineering clients over TCP 5760 and legacy tools over UDP 14550. WebSocket has no JSON wrapper: it carries wire-compatible binary MAVLink v2 frames.
const ws = new WebSocket("ws://<board-ip>:8765");
ws.binaryType = "arraybuffer";
ws.onmessage = (event) => {
decodeMavlink(new Uint8Array(event.data));
};
ws.send(encodeCommandLong(sysid, compid, cmd, params));Contracts for drivers and on-vehicle logic
| Class | Purpose |
|---|---|
| CameraDriver | CSI, USB UVC, IP and vendor-SDK cameras |
| GimbalDriver | Pan, tilt, roll and gimbal telemetry |
| LidarDriver | LiDAR and rangefinder devices |
| GpsDriver | GPS/GNSS receivers |
| EscDriver | ESC drivers and return telemetry |
| VisionClient | Frames and detections from the on-vehicle vision bus |
API key permissions limit the scope of action
| Level | Allowed operations |
|---|---|
| read | Telemetry, status, configuration, logs and parameters without state changes |
| command | Flight commands; includes read |
| mission | Upload and execute mission files; includes command |
| config | Change agent and FC configuration; includes read |
| admin | Updates, service restarts, key management and full access |
Keep the key secret and do not include it in public logs, screenshots or client bundles. Browser integrations should use short-lived scoped credentials rather than permanent admin keys.
MAVLink v2 signing without storing the key on the agent
The ground station creates a 32-byte key and stores it in the browser as a non-extractable Web Crypto key. The capability endpoint checks the firmware and availability of signing parameters. After one-time enrollment, the flight controller verifies the HMAC-SHA256 tag on every outbound frame. The agent remains a transparent pipe and does not store the signing key.
GET /api/mavlink/signing/capability
X-KairOS-Key: <your-key>
{
"supported": true,
"reason": "ok",
"firmware_name": "ArduPilot",
"firmware_version": "4.5.0",
"signing_params_present": true
}