2026-01-04 13:32:09 -05:00
2026-01-19 11:50:51 -05:00
2026-01-19 11:50:51 -05:00
2026-01-17 17:10:58 -05:00
2026-01-18 17:08:27 -05:00
2026-01-18 17:06:55 -05:00
2026-01-17 17:06:32 -05:00
2026-01-17 17:06:32 -05:00
2026-01-18 17:06:55 -05:00

ubiquiti-clients

Go client libraries for interacting with Ubiquiti network devices via their REST APIs, plus a CLI tool.

⚠️ Disclaimer: These libraries are based on reverse-engineered API calls. They are not official Ubiquiti products and are subject to change if the device firmware changes.

Packages

toughswitch

A client library for interacting with Ubiquiti ToughSwitch devices (specifically tested with ToughSwitch POE Pro (TS-8-PRO)) via their internal REST API.

Features

  • Authentication: Handles login and session token management automatically (or explicitly via Login).
  • Multi-Device Support: Manage multiple devices with a single client instance.
  • Data Retrieval:
    • System Information: Hostname, uptime, firmware version, etc.
    • Interfaces: Status, POE settings, link speed, statistics.
    • VLANs: Configuration and trunk information.
    • Services: SSH, Telnet, Web Server, NTP, SNMP, etc.
    • Statistics: Real-time throughput, errors, and resource usage.
    • Discovery: Neighbor discovery via UBNT protocol.

edgeos

A client library for interacting with Ubiquiti EdgeOS devices (EdgeRouter, EdgeSwitch) via their REST API.

Features

  • Authentication: Handles login and session management automatically (or explicitly via Login).
  • Multi-Device Support: Manage multiple devices with a single client instance.
  • Data Retrieval:
    • System Configuration: Hostname, domain name, and other system settings.
    • Interface Configuration: Ethernet and switch interface settings, including PoE.
    • VLAN Configuration: VLAN assignments, PVID, and tagged VLANs.
    • Device Information: Model, ports, PoE capabilities, and features.

CLI Tool

A command-line tool is included for quick device queries.

Installation

go install gitea.libretechconsulting.com/rmcguire/ubiquiti-clients/cmd@latest

Configuration

Create a config file (YAML or JSON):

logLevel: info
logFormat: console

clients:
  - name: switch1
    type: toughswitch
    host: 192.168.1.1
    user: ubnt
    pass: password
    insecure: true
    timeout: 10s

  - name: router1
    type: edgeos
    host: 192.168.1.2
    user: ubnt
    pass: password
    insecure: true
    timeout: 10s

Environment variables can also be used (and take priority over config file):

  • LOG_LEVEL, LOG_FORMAT for top-level settings
  • CLIENT_0_NAME, CLIENT_0_HOST, CLIENT_0_TYPE, etc. for client array

Usage

# Get info from a single device
cmd --config config.yaml get device switch1

# Get info from all configured devices
cmd --config config.yaml get devices

# With flags
cmd --config config.yaml get device switch1 --pretty --color

Library Installation

# For ToughSwitch
go get gitea.libretechconsulting.com/rmcguire/ubiquiti-clients/pkg/toughswitch

# For EdgeOS
go get gitea.libretechconsulting.com/rmcguire/ubiquiti-clients/pkg/edgeos

Library Usage

ToughSwitch Basic Example

package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"gitea.libretechconsulting.com/rmcguire/ubiquiti-clients/pkg/toughswitch"
)

func main() {
	ctx := context.Background()

	// Configure your device(s)
	configs := []toughswitch.Config{
		{
			Host:     "192.168.1.1",
			Username: "ubnt",
			Password: "password",
			Insecure: true, // Set to true if using self-signed certs
			Timeout:  10 * time.Second,
		},
	}

	// Initialize the client
	client := toughswitch.MustNew(ctx, configs)

	// Optionally pre-authenticate (otherwise happens automatically on first request)
	if err := client.Login(ctx, "192.168.1.1"); err != nil {
		log.Fatalf("Failed to login: %v", err)
	}

	// Fetch system information
	deviceHost := "192.168.1.1"
	system, err := client.GetSystem(ctx, deviceHost)
	if err != nil {
		log.Fatalf("Failed to get system info: %v", err)
	}

	fmt.Printf("Connected to: %s (Timezone: %s)\n", system.Hostname, system.Timezone)

	// Fetch interfaces
	ifaces, err := client.GetInterfaces(ctx, deviceHost)
	if err != nil {
		log.Fatalf("Failed to get interfaces: %v", err)
	}

	for _, iface := range ifaces {
		fmt.Printf("Interface %s: %s (POE: %s)\n",
			iface.Identification.ID,
			iface.Status.Speed,
			iface.Port.POE,
		)
	}
}

EdgeOS Basic Example

package main

import (
	"context"
	"fmt"
	"log"
	"time"

	"gitea.libretechconsulting.com/rmcguire/ubiquiti-clients/pkg/edgeos"
)

func main() {
	ctx := context.Background()

	// Configure your device(s)
	configs := []edgeos.Config{
		{
			Host:     "192.168.1.1",
			Username: "ubnt",
			Password: "ubnt",
			Insecure: true, // Set to true if using self-signed certs
			Timeout:  10 * time.Second,
		},
	}

	// Initialize the client
	client := edgeos.MustNew(ctx, configs)

	// Optionally pre-authenticate (otherwise happens automatically on first request)
	if err := client.Login(ctx, "192.168.1.1"); err != nil {
		log.Fatalf("Failed to login: %v", err)
	}

	// Fetch device information
	deviceHost := "192.168.1.1"
	authInfo, err := client.GetAuthInfo(ctx, deviceHost)
	if err != nil {
		log.Fatalf("Failed to get auth info: %v", err)
	}

	fmt.Printf("Connected to: %s (%s) with %d ports\n",
		authInfo.ModelName, authInfo.Model, authInfo.Ports)

	// Fetch system configuration
	system, err := client.GetSystem(ctx, deviceHost)
	if err != nil {
		log.Fatalf("Failed to get system config: %v", err)
	}

	fmt.Printf("Hostname: %s, Domain: %s\n", system.HostName, system.DomainName)

	// Fetch interfaces
	interfaces, err := client.GetInterfaces(ctx, deviceHost)
	if err != nil {
		log.Fatalf("Failed to get interfaces: %v", err)
	}

	for name, config := range interfaces.Ethernet {
		fmt.Printf("Interface %s: %s (Speed: %s, Duplex: %s)\n",
			name,
			config.Description,
			config.Speed,
			config.Duplex,
		)
	}
}

ToughSwitch: Retrieving Statistics

stats, err := client.GetStatistics(ctx, "192.168.1.1")
if err != nil {
    log.Fatal(err)
}

for _, stat := range stats {
    // Device level stats
    fmt.Printf("CPU Usage: %d%%\n", stat.Device.CPU[0].Usage)

    // Per-interface stats
    for _, iface := range stat.Interfaces {
        fmt.Printf("[%s] Rx: %d bps, Tx: %d bps\n",
            iface.Name,
            iface.Statistics.RxRate,
            iface.Statistics.TxRate,
        )
    }
}

Working with Multiple Devices

Both clients are designed to handle multiple devices concurrently.

// ToughSwitch example
configs := []toughswitch.Config{
    {Host: "192.168.1.1", ...},
    {Host: "192.168.1.2", ...},
}
client := toughswitch.MustNew(ctx, configs)

// Get info for all configured devices in parallel
allSystems, err := client.GetAllSystems(ctx)
if err != nil {
    log.Printf("Error fetching some systems: %v", err)
}

for host, sys := range allSystems {
    fmt.Printf("[%s] Hostname: %s\n", host, sys.Hostname)
}

// EdgeOS example
edgeConfigs := []edgeos.Config{
    {Host: "192.168.2.1", ...},
    {Host: "192.168.2.2", ...},
}
edgeClient := edgeos.MustNew(ctx, edgeConfigs)

// Get config for all configured devices in parallel
allConfigs, err := edgeClient.GetAllConfigs(ctx)
if err != nil {
    log.Printf("Error fetching some configs: %v", err)
}

for host, cfg := range allConfigs {
    fmt.Printf("[%s] Hostname: %s\n", host, cfg.System.HostName)
}

Supported Endpoints

ToughSwitch

Method Description
Login Explicit authentication (also happens automatically on 401)
GetSystem General system configuration and status
GetInterfaces Interface configuration and status
GetVLANs VLAN and Trunk configuration
GetServices State of running services (SSH, NTP, etc.)
GetStatistics Performance metrics
GetNeighbors Discovered UBNT neighbors
GetDevice Hardware and capabilities info

All Get* methods have corresponding GetAll* variants for multi-device operations.

EdgeOS

Method Description
Login Explicit authentication (also happens automatically on 401)
GetConfig Complete device configuration
GetAuthInfo Device authentication and feature information
GetInterfaces Interface configuration (ethernet and switch)
GetSystem System configuration (hostname, domain)

All Get* methods have corresponding GetAll* variants for multi-device operations.

License

MIT

Description
Go client package and types for Ubiquiti devices that lack documented APIs or existing open-source support.
Readme 116 KiB
Languages
Go 100%