eero-go is an unofficial, highly robust Go client library for interacting with the Eero Mesh Router API.
Designed for performance and security, it seamlessly handles eero's two-step authentication, manages API cookie sessions thread-safely, and surfaces strongly-typed structs for your local network topology.
Disclaimer: This is an unofficial open-source library and is not affiliated with, endorsed by, or supported by Eero or Amazon.
- No External Dependencies: Built entirely upon the Go standard library (
net/http,context,encoding/json). - Secure By Default: Hardened
http.Transportagainst connection exhaustion, 5MBio.LimitReadercaps against OOM attacks, and strictly managedcookiejarstates protecting session leaks. - Idiomatic Typings: Extracts eero's deeply nested JSON envelopes into clean, traversable Go structs using Go 1.18+ Generics, dropping missing data fields safely to pointer
nilvalues.
The library is modularized by functional domains to provide strict operational boundaries:
client.go: Centralizes the HTTPClient, enforces security boundaries, limits payload sizes, and manages the thread-safenet/http/cookiejar.auth.go: Manages the undocumented 2-step verification challenge (Email/Phone -> OTP).account.go: Retrieves top-level user account details and base networking routing URLs.network.go: Safely parses Eero's deeply nested JSON payloads to expose granular telemetry (IPv6Leases,DHCPallocations,PremiumDNSadblocking features, etc) alongside network speeds and health metrics.device.go: Exhaustively lists all connected and offline devices with detailed connectivity reporting (signal noise ratios,vlan_idtags, bandwidthBpsthroughputs) mapping absent optional fields (like IPs for offline devices) tonilusing*stringpointers.profile.go: Manages groupings of fully mappedDevicetopologies and offers the ability to pause/unpause internet blocks globally across a user.
flowchart TD
User([User / CLI]) --> |Initiates| Client[Go Client Interface]
Client --> CacheCheck{Check Local Session<br>.eero_session.json}
CacheCheck -->|Exists & Valid| CookieJar[Inject Token into http.CookieJar]
CacheCheck -->|Missing / Expired| AuthFlow[Interactive Auth Flow]
AuthFlow -->|1. /login Email Request| EeroCloud[Eero Cloud API]
AuthFlow -->|2. /login/verify 2FA Code| EeroCloud
AuthFlow -.-> |Persist Token| CacheCheck
CookieJar --> ServiceRequest[Execute Service Request<br>Account / Network / Device]
ServiceRequest -->|Authenticated HTTP GET/POST| EeroCloud
EeroCloud -->|Raw JSON Response| Unmarshal["Generic Envelope Unmarshaler<br>EeroResponse#91;T#93;"]
Unmarshal -->|Type-Safe Go Structs| User
Authentication with Eero relies on a persistent session cookie (s=user_token). The eero-go client abstracts this away entirely:
- Upon successful login, the token is transparently injected into the underlying
http.CookieJar. - For long-running or local CLI tools, you can extract this
user_tokenand save it locally (e.g., to a restrictive0600permission.eero_session.jsonfile). - On subsequent boots, use
client.SetSessionCookie(token)to instantly restore authorization without pinging users for another 2FA code.
You need Go 1.21 or higher installed.
go get github.com/arvarik/eero-goThe repository includes a fully-functional interactive CLI example at cmd/example/main.go. This script demonstrates how to authenticate, cache your session securely, and fetch live network speeds and connected devices.
Execute the example directly from the command line:
go run ./cmd/exampleIf this is your first time connecting, the script will prompt you for your Eero account email or phone number. A verification code will be sent to your device.
Enter your eero email: myemail@example.com
Check your email for the code: 123456
Authenticated!Upon successful login, eero-go extracts your authenticated user_token and saves it to a hidden file in your current directory named .eero_session.json.
Why is this needed?
Eero's API enforces strict rate limits on authentication requests. By caching the token locally (with strict 0600 file permissions), the client can instantly bypass the 2-step verification challenge on subsequent runs. This is critical for automated cron jobs or home lab monitoring scripts that need to poll the API repeatedly without spamming your phone with verification texts.
To reset your session, simply delete the .eero_session.json file.
Once you have the .eero_session.json file, you can easily use the extracted user_token to make direct API calls from your command line using curl.
Here are examples for all the available read-only (GET) endpoints:
# Extract the token and save it to a variable (requires jq)
TOKEN=$(jq -r '.user_token' .eero_session.json)
# 1. Fetch your account details and networks
curl -s -H "Cookie: s=$TOKEN" "https://api-user.e2ro.com/2.2/account" | jq
# 2. Fetch specific network details (replace {network_id} with your network's ID from Step 1)
curl -s -H "Cookie: s=$TOKEN" "https://api-user.e2ro.com/2.2/networks/{network_id}" | jq
# 3. Fetch all connected and offline devices for a network
curl -s -H "Cookie: s=$TOKEN" "https://api-user.e2ro.com/2.2/networks/{network_id}/devices" | jq
# 4. Fetch all device profiles (e.g., family member groupings) for a network
curl -s -H "Cookie: s=$TOKEN" "https://api-user.e2ro.com/2.2/networks/{network_id}/profiles" | jqThe library provides individual services attached to the core Client. Below are comprehensive examples of what you can extract and enact using each service.
Retrieve the overarching account details, your registered email/phone, and extract the internal URLs mapping to your meshes.
acct, err := client.Account.Get(ctx)
fmt.Println("Account Name:", acct.Name) // "Home Mesh"
fmt.Println("Network URL:", acct.Networks.Data[0].URL) // "/2.2/networks/12345"Pull granular details about a specific network, including speeds, online status, guest networking, and physically connected Eero hardware Nodes. You can also trigger a full network reboot.
// Fetch network status and speeds
net, err := client.Network.Get(ctx, networkURL)
fmt.Println("Status:", net.Status) // "online"
fmt.Printf("Speed: %.1f %s Down\n", net.Speed.Down.Value, net.Speed.Down.Units) // 850.5 Mbps
// Iterate over the physical Eero router boxes
for _, eeroNode := range net.Eeros.Data {
fmt.Printf("Model: %s, Firmware: %s, Gateway: %t\n",
eeroNode.Model, eeroNode.OSVersion, eeroNode.Gateway)
}
// Reboot the entire network
err = client.Network.Reboot(ctx, networkURL)Scan the network for all known client devices (phones, laptops, IoT gadgets). This handles both currently connected devices and offline devices, safely parsing absent JSON fields.
devices, err := client.Device.List(ctx, networkURL)
for _, d := range devices {
// Safely dereference optional Nickname pointer
name := "Unknown Device"
if d.Nickname != nil {
name = *d.Nickname
}
fmt.Printf("Device: %s\n", name)
fmt.Printf("Connected: %t (Type: %s)\n", d.Connected, d.DeviceType)
fmt.Printf("Last Active: %s\n", d.LastActive.Format(time.RFC3339))
if d.Connectivity.ScoreBars > 0 {
fmt.Printf("Wireless Signal Strength: %d/5 (%s)\n", d.Connectivity.ScoreBars, d.Connectivity.Signal)
}
}Profiles group devices together (e.g., "Kids Devices"). You can fetch these profiles and pause or unpause internet access to grouped devices globally.
profiles, err := client.Profile.List(ctx, networkURL)
for _, p := range profiles {
fmt.Printf("Profile: %s (Paused: %t)\n", p.Name, p.Paused)
// Example: Pause internet for this specific profile
// client.Profile.Pause(ctx, p.URL)
}If you manage your session tokens externally (e.g., in a secure vault like Hashicorp Vault or a Kubernetes Secret), you can inject the token directly into the client's thread-safe cookie jar, bypassing the Auth service completely.
client.SetSessionCookie("your-secret-user-token")The test suite validates memory safety limits and concurrency using standard library httptest mock servers and parallel table execution. No third-party mocking libraries are strictly required!
# Run the test suite with the race detector
make testIf you are contributing to this library, you should run the setup command immediately after cloning. This automatically configures standard Git hooks to invoke the Go linter before allowing commits:
# Sets `core.hooksPath` to `.githooks` enabling the pre-commit action automatically
make setupThe included Makefile handles cross-compilation for headless servers and minimal Linux environments (like Proxmox or TrueNAS).
# Compile for standard 64-bit Linux machines
make build-linux-amd64
# Compile for ARM servers (e.g., Raspberry Pi 4/5)
make build-linux-arm64
# Clean up build artifacts
make cleanThis project is licensed under the MIT License - see the LICENSE file for details.