Download OpenAPI specification:Download
The API service exists for communication between service containers and to support external requests from the web front end or CLI tools.
The internal APIs run over unix sockets and rely on filesystem namespaces for authentication.
Currently there are four internal APIs:
The external API runs over port :80 or can optionally be configured to run over SSL on port :443.
On the device, the following files contain credentials for access.
config/auth/auth_users.json is a JSON file with a dictionary for username, password pairsconfigs/auth/auth_tokens.json is a JSON file with a list of authentication tokensconfigs/auth/otp_settings.json is a JSON file with OTP user configuration.The API supports Basic Authentication based on the auth_users file, using the Basic Schema.
To implement this, a client should include an "Authorization: Basic" header with the credentials formatted as base64(username:password). For a javascript example, see the frontend's Api.js.
basicThe API also supports Bearer Tokens, based on the auth_tokens file.
To implement this, a client should include an "Authorization: Bearer" token. See Swagger's page for more examples.
bearerAPI extensions operate through a reverse proxy into a unix socket. They allow for hosting extensions to the API on the same web origin while running in a different process or container.
Extensions are configured in configs/base/api.json
This example shows the mapping of unix://state/dns/dns_block_plugin to http://APIHOST/plugins/dns/block/
{
"Plugins" : [{
"Name": "dns block extension",
"URI": "dns/block",
"UnixPath": "/state/dns/dns_block_plugin"
}]
}
See the API documentation for plugins here
Returns a map of registered devices, indexed by MAC address
curl -u "admin:pass" \ "http://192.168.2.1/devices"
{- "11:22:33:44:55:61": {
- "Name": "rpi4",
- "MAC": "11:22:33:44:55:61",
- "WGPubKey": "pubkey",
- "VLANTag": "vlantag",
- "RecentIP": "192.168.2.102",
- "PSKEntry": {
- "Type": "sae",
- "Psk": "password"
}, - "Policies": [
- "wan",
- "dns",
- "lan_upstream"
], - "Groups": [
- "cameras",
- "tvs"
], - "DeviceTags": [
- "private"
]
}, - "11:22:33:44:55:62": {
- "Name": "rpi4",
- "MAC": "11:22:33:44:55:61",
- "WGPubKey": "pubkey",
- "VLANTag": "vlantag",
- "RecentIP": "192.168.2.102",
- "PSKEntry": {
- "Type": "sae",
- "Psk": "password"
}, - "Policies": [
- "wan",
- "dns",
- "lan_upstream"
], - "Groups": [
- "cameras",
- "tvs"
], - "DeviceTags": [
- "private"
]
}
}Map of devices to sync, indexed by MAC address
additional property | object (DeviceEntry) | ||||||||||||||||||
| |||||||||||||||||||
{- "11:22:33:44:55:61": {
- "Name": "rpi4",
- "MAC": "11:22:33:44:55:61",
- "WGPubKey": "pubkey",
- "VLANTag": "vlantag",
- "RecentIP": "192.168.2.102",
- "PSKEntry": {
- "Type": "sae",
- "Psk": "password"
}, - "Policies": [
- "wan",
- "dns",
- "lan_upstream"
], - "Groups": [
- "cameras",
- "tvs"
], - "DeviceTags": [
- "private"
]
}, - "11:22:33:44:55:62": {
- "Name": "rpi4",
- "MAC": "11:22:33:44:55:61",
- "WGPubKey": "pubkey",
- "VLANTag": "vlantag",
- "RecentIP": "192.168.2.102",
- "PSKEntry": {
- "Type": "sae",
- "Psk": "password"
}, - "Policies": [
- "wan",
- "dns",
- "lan_upstream"
], - "Groups": [
- "cameras",
- "tvs"
], - "DeviceTags": [
- "private"
]
}
}Array of device identities to delete
[- "11:22:33:44:55:66"
]{- "deleted": [
- "11:22:33:44:55:66"
], - "count": 1
}Get a Device specified by the MAC address in the identity parameter. Requires OTP Code
| identity required | string Example: 11:22:33:44:55:61 MAC address |
curl -u "admin:pass" -X DELETE -H "X-JWT-OTP:..." \ "http://192.168.2.1/device?identity=11:22:33:44:55:66"
{- "Name": "rpi4",
- "MAC": "11:22:33:44:55:61",
- "WGPubKey": "pubkey",
- "VLANTag": "vlantag",
- "RecentIP": "192.168.2.102",
- "PSKEntry": {
- "Type": "sae",
- "Psk": "password"
}, - "Policies": [
- "wan",
- "dns",
- "lan_upstream"
], - "Groups": [
- "cameras",
- "tvs"
], - "DeviceTags": [
- "private"
]
}Update information specified by the MAC address in the identity parameter. All fields are optional. If a PSKEntry.PskType is set and a PSKEntry.Psk is not set, one will be generated and returned. To create a wildcard PSK for adding a new device, use the string "pending" for the identity.
| identity required | string Example: 11:22:33:44:55:61 MAC address |
Device object
| Name | string Client Name |
| MAC | string HW address |
| WGPubKey | string PubKey |
| VLANTag | string VLANTag |
| RecentIP | string RecentIP |
object (PSKEntry) | |
| Policies | Array of strings Policies for Device |
| Groups | Array of strings Interconnected Groups of Devices |
| DeviceTags | Array of strings Tags for Device |
{- "Name": "rpi4",
- "MAC": "11:22:33:44:55:61",
- "WGPubKey": "pubkey",
- "VLANTag": "vlantag",
- "RecentIP": "192.168.2.102",
- "PSKEntry": {
- "Type": "sae",
- "Psk": "password"
}, - "Policies": [
- "wan",
- "dns",
- "lan_upstream"
], - "Groups": [
- "cameras",
- "tvs"
], - "DeviceTags": [
- "private"
]
}{- "Name": "rpi4",
- "MAC": "11:22:33:44:55:61",
- "WGPubKey": "pubkey",
- "VLANTag": "vlantag",
- "RecentIP": "192.168.2.102",
- "PSKEntry": {
- "Type": "sae",
- "Psk": "password"
}, - "Policies": [
- "wan",
- "dns",
- "lan_upstream"
], - "Groups": [
- "cameras",
- "tvs"
], - "DeviceTags": [
- "private"
]
}Delete a Device specified by the MAC address in the identity parameter
| identity required | string Example: 11:22:33:44:55:61 MAC address |
curl -u "admin:pass" -X DELETE \ "http://192.168.2.1/device?identity=11:22:33:44:55:66"
Identities plus groups/tags/policies to add
| Identities | Array of strings Device identities to update (MAC address or WireGuard public key) |
| Groups | Array of strings Groups to add to each device |
| Tags | Array of strings Tags to add to each device |
| Policies | Array of strings Policies to add to each device (must be bulk-settable) |
{- "Identities": [
- "11:22:33:44:55:66"
], - "Groups": [
- "dns",
- "wan"
], - "Tags": [
- "lab"
], - "Policies": [
- "lan"
]
}{- "updated": [
- "11:22:33:44:55:66"
], - "count": 1
}If the group does not exist, it will be created. If it exists it will be updated. Fields are optional.
Group object
| Name | string Unique Group Name |
| Disabled | boolean If Group is disabled |
| GroupTags | Array of strings Tags for Group |
{- "Name": "vpn",
- "Disabled": false,
- "GroupTags": [
- [
- "private"
]
]
}Group object
| Name | string Unique Group Name |
| Disabled | boolean If Group is disabled |
| GroupTags | Array of strings Tags for Group |
{- "Name": "vpn",
- "Disabled": false,
- "GroupTags": [
- [
- "private"
]
]
}curl -u "admin:pass" \ "http://192.168.2.1/ip/addr"
[- {
- "ifindex": 1,
- "ifname": "eth0",
- "flags": [
- "BROADCAST"
], - "mtu": 1550,
- "qdisc": "mq",
- "operstate": "UP",
- "group": "default",
- "txqlen": 1000,
- "link_type": "ether",
- "address": "11:22:33:44:55:66",
- "broadcast": "ff:ff:ff:ff:ff:ff",
- "addr_info": [
- {
- "family": "inet6",
- "local": "::1",
- "prefixlen": 64,
- "scope": "link",
- "valid_life_time": 4294967295,
- "preferred_life_time": "preferred_life_time"
}
]
}
]Returns the output of nft -j for the verdict map specificed by the name parameter
| name required | string Name of the nfmap to fetch |
curl -u "admin:pass" \ "http://192.168.2.1/nfmap/dns_access"
{ }curl -u "admin:pass" \ "http://192.168.2.1/arp"
[- {
- "IP": "192.168.2.142",
- "HWType": "0x1",
- "Flags": "0x6",
- "MAC": "11:22:33:44:55:66",
- "Mask": "*",
- "Device": "wlan1.4097"
}
]Returns the output of iw dev iface scan in json format.
Note: the specified interface needs to be in managed mode.
| iface required | string Example: wlan0 interface |
curl -u "admin:pass" \ "http://192.168.2.1/iw/dev/wlan0/scan"
[- {
- "bssid": "11:11:11:11:11:11",
- "interface": "wlan0",
- "freq": 2412,
- "ssid": "sample_ssid1",
- "authentication_suites": "PSK",
- "signal_dbm": -64
}
]Sets or updates the subnet configuration. This will overwrite the existing configuration.
| TinyNets required | Array of strings List of subnet pools. |
| LeaseTime required | string Duration of the DHCP lease time. |
{- "TinyNets": [
- "string"
], - "LeaseTime": "string"
}Updates the DNS settings. This operation overwrites the existing settings.
| UpstreamTLSHost required | string DNS name of the upstream TLS host. |
| UpstreamIPAddress required | string IP address of the upstream DNS server. |
| TlsDisable required | boolean Flag to disable TLS. |
{- "UpstreamTLSHost": "string",
- "UpstreamIPAddress": "string",
- "TlsDisable": true
}Performs an ICMP ping test from a specified interface to a given address
| interface required | string Network interface to use for the ping test |
| address required | string IP address to ping |
curl -X PUT http://localhost/ping/eth0/8.8.8.8
[- "10.523ms",
- "9.872ms",
- "11.245ms",
- "10.101ms"
]Performs a UDP ping test from a specified interface to a given address
| interface required | string Network interface to use for the UDP ping test |
| address required | string IP address and port to ping |
curl -X PUT http://localhost/ping/eth0/8.8.8.8:53/udp
[- "15.789ms",
- "14.234ms",
- "16.012ms",
- "15.456ms"
]curl -u "admin:pass" \ "http://192.168.2.1/topology"
{- "GeneratedAt": "2024-03-14T10:12:00Z",
- "Nodes": [
- {
- "ID": "dev:11:22:33:44:55:66",
- "Kind": "device",
- "Name": "laptop",
- "MAC": "11:22:33:44:55:66",
- "IP": "192.168.2.20",
- "TinyNet": "192.168.2.20/30",
- "VLANTag": "10",
- "ConnType": "wifi",
- "Iface": "wlan0",
- "SSID": "SPR",
- "Radio": {
- "Channel": 36,
- "Freq": 5180,
- "Modes": [
- "ac",
- "ax"
], - "Stations": 3
}, - "Groups": [
- "dns",
- "wan"
], - "Policies": [
- "lan"
], - "Tags": [
- "lab"
], - "Signal": {
- "RSSI": -55,
- "TxRate": 866,
- "RxRate": 866,
- "Caps": [
- "VHT",
- "HE"
]
}, - "Online": true,
- "Isolated": false,
- "Style": { },
- "DHCPFirstTime": "2024-03-13T23:43:39Z",
- "DHCPLastTime": "2024-03-14T10:12:00Z"
}
], - "Edges": [
- {
- "From": "dev:11:22:33:44:55:66",
- "To": "iface:wlan0",
- "Layer": "l1",
- "Kind": "wifi",
- "Metric": -55,
- "Bidir": true
}
], - "Sinks": [
- {
- "ID": "plugin:mesh:sink:tailscale",
- "Name": "tailscale",
- "Iface": "tailscale0",
- "IP": "100.64.0.1",
- "Online": true
}
]
}Returns the firewall API configuration
curl -u "admin:pass" \ "http://192.168.2.1/firewall/config"
{- "ForwardingRules": [
- {
- "DstIP": "1.2.3.4",
- "SrcIP": "0.0.0.0/24",
- "SrcPort": "0-10",
- "DstPort": "any",
- "Protocol": "tcp"
}
], - "BlockRules": [
- {
- "DstIP": "1.2.3.4",
- "SrcIP": "0.0.0.0/24",
- "Protocol": "tcp"
}
], - "ForwardingBlockRules": [
- {
- "DstIP": "1.2.3.4",
- "SrcIP": "0.0.0.0/24",
- "DstPort": "0-65535",
- "Protocol": "tcp"
}
], - "ServicePorts": [
- {
- "UpstreamEnabled": false,
- "Port": "22",
- "Protocol": "tcp"
}
]
}Use 'any' for the port to forward all ports. Specify a port or a port range otherwise
| DstIP | string |
| SrcIP | string |
| SrcPort | string/any|[0-9]+/ |
| DstPort | string/any|[0-9]+/ |
| Protocol | string/udp|tcp/ |
{- "DstIP": "1.2.3.4",
- "SrcIP": "0.0.0.0/24",
- "SrcPort": "0-10",
- "DstPort": "any",
- "Protocol": "tcp"
}Delete forwarding rule with matching contents
Use 'any' for the port to forward all ports. Specify a port or a port range otherwise
| DstIP | string |
| SrcIP | string |
| SrcPort | string/any|[0-9]+/ |
| DstPort | string/any|[0-9]+/ |
| Protocol | string/udp|tcp/ |
{- "DstIP": "1.2.3.4",
- "SrcIP": "0.0.0.0/24",
- "SrcPort": "0-10",
- "DstPort": "any",
- "Protocol": "tcp"
}Delete blocking rule with matching contents
FirewallBlock
| DstIP | string |
| SrcIP | string |
| Protocol | string/udp|tcp/ |
{- "DstIP": "1.2.3.4",
- "SrcIP": "0.0.0.0/24",
- "Protocol": "tcp"
}Add Forward Block Rule, to block outbound traffic
FirewallBlockForward
| DstIP | string |
| SrcIP | string |
| DstPort | string |
| Protocol | string/udp|tcp/ |
{- "DstIP": "1.2.3.4",
- "SrcIP": "0.0.0.0/24",
- "DstPort": "0-65535",
- "Protocol": "tcp"
}Delete blocking rule with matching contents
FirewallBlockForward
| DstIP | string |
| SrcIP | string |
| DstPort | string |
| Protocol | string/udp|tcp/ |
{- "DstIP": "1.2.3.4",
- "SrcIP": "0.0.0.0/24",
- "DstPort": "0-65535",
- "Protocol": "tcp"
}Service Ports are ports that run on the SPR router itself. They can be for LAN clients only or for upstream also
ServicePort
| UpstreamEnabled | boolean Reachable from WAN/Upstream Interface |
| Port | string |
| Protocol | string/tcp/ Only TCP services are currently supported |
{- "UpstreamEnabled": false,
- "Port": "22",
- "Protocol": "tcp"
}Delete service port from allow list
ServicePort
| UpstreamEnabled | boolean Reachable from WAN/Upstream Interface |
| Port | string |
| Protocol | string/tcp/ Only TCP services are currently supported |
{- "UpstreamEnabled": false,
- "Port": "22",
- "Protocol": "tcp"
}Endpoints store common destinations for the UI to populate fields with
| RuleName | string |
| Disabled | boolean |
| Protocol | string |
| IP | string |
| Domain | string |
| Port | string |
| Tags | Array of strings Tags for Device |
{- "RuleName": "string",
- "Disabled": true,
- "Protocol": "string",
- "IP": "1.2.3.4",
- "Domain": "www.domain.com",
- "Port": "22",
- "Tags": [
- "private"
]
}Delete an existing endpoint from the firewall configuration.
| RuleName | string |
| Disabled | boolean |
| Protocol | string |
| IP | string |
| Domain | string |
| Port | string |
| Tags | Array of strings Tags for Device |
{- "RuleName": "string",
- "Disabled": true,
- "Protocol": "string",
- "IP": "1.2.3.4",
- "Domain": "www.domain.com",
- "Port": "22",
- "Tags": [
- "private"
]
}Configures a multicast port in the firewall.
| Upstream | boolean Reachable from Uplinks |
| Port | string |
{- "Upstream": true,
- "Port": "22"
}Adds a custom interface rule to the firewall.
| Interface | string interface name |
| SrcIP | string IP or CIDR assigned to interface |
| RouteDst | string IP destination to route to, for example container host IP |
| Policies | Array of strings Policies for Interface |
| Groups | Array of strings Groups to join Interfaces to Devices |
| Tags | Array of strings Tags to apply. NOTE, no impact for now |
{- "Interface": "wlan1",
- "SrcIP": "172.16.0.0/16",
- "RouteDst": "172.12.0.2",
- "Policies": [
- "api",
- "wan",
- "dns",
- "lan_upstream"
], - "Groups": [
- "cameras"
], - "Tags": [
- "private"
]
}Removes a custom interface rule from the firewall.
| Interface | string interface name |
| SrcIP | string IP or CIDR assigned to interface |
| RouteDst | string IP destination to route to, for example container host IP |
| Policies | Array of strings Policies for Interface |
| Groups | Array of strings Groups to join Interfaces to Devices |
| Tags | Array of strings Tags to apply. NOTE, no impact for now |
{- "Interface": "wlan1",
- "SrcIP": "172.16.0.0/16",
- "RouteDst": "172.12.0.2",
- "Policies": [
- "api",
- "wan",
- "dns",
- "lan_upstream"
], - "Groups": [
- "cameras"
], - "Tags": [
- "private"
]
}Configures ICMP options in the firewall.
| PingLan required | boolean Allow ping from LAN |
| PingWan required | boolean Allow ping from WAN/upstream |
{- "PingLan": true,
- "PingWan": false
}curl http://localhost/multicastSettings
{- "Disabled": false,
- "Addresses": [
- {
- "Address": "224.0.0.251:5353"
}
], - "DisableMDNSAdvertise": false,
- "MDNSName": "MyDevice"
}Updates the multicast settings
| Disabled | boolean Whether multicast is disabled |
Array of objects (MulticastAddress) List of multicast addresses | |
| DisableMDNSAdvertise | boolean Whether MDNS advertisement is disabled |
| MDNSName | string MDNS name |
{- "Disabled": false,
- "Addresses": [
- {
- "Address": "224.0.0.251:5353"
}
], - "DisableMDNSAdvertise": false,
- "MDNSName": "MyDevice"
}{- "Disabled": false,
- "Addresses": [
- {
- "Address": "224.0.0.251:5353"
}
], - "DisableMDNSAdvertise": false,
- "MDNSName": "MyDevice"
}curl -u "admin:pass" -X GET \ "http://192.168.2.1/firewall/geo_block/config"
{- "Enabled": true,
- "DenyCountries": [
- "CN"
], - "DenyASNs": [
- {
- "ASN": 13335,
- "Name": "CLOUDFLARENET"
}
], - "Lists": [
], - "RefreshSeconds": 86400
}GeoBlockConfig
| Enabled | boolean Master enable for geo/ASN blocking |
| DenyCountries | Array of strings Two-letter ISO country codes to block |
Array of objects (GeoASN) Autonomous Systems to block | |
Array of objects (GeoBlockList) External block lists to fetch | |
| RefreshSeconds | integer Refresh interval in seconds (minimum 3600, defaults to 86400) |
{- "Enabled": true,
- "DenyCountries": [
- "CN"
], - "DenyASNs": [
- {
- "ASN": 13335,
- "Name": "CLOUDFLARENET"
}
], - "Lists": [
], - "RefreshSeconds": 86400
}{- "Enabled": true,
- "DenyCountries": [
- "CN"
], - "DenyASNs": [
- {
- "ASN": 13335,
- "Name": "CLOUDFLARENET"
}
], - "Lists": [
], - "RefreshSeconds": 86400
}curl -u "admin:pass" -X GET \ "http://192.168.2.1/firewall/geo_block/status"
{- "Enabled": true,
- "LastRefresh": "2026-07-09T12:00:00Z",
- "RangesProgrammed": 1024,
- "Sources": [
- {
- "Type": "asn",
- "Key": "AS13335",
- "Ranges": 42,
- "ASNs": 3,
- "LastFetch": "2026-07-09T12:00:00Z",
- "Error": ""
}
]
}curl -u "admin:pass" -X PUT \ "http://192.168.2.1/firewall/geo_block/refresh"
{- "Enabled": true,
- "LastRefresh": "2026-07-09T12:00:00Z",
- "RangesProgrammed": 1024,
- "Sources": [
- {
- "Type": "asn",
- "Key": "AS13335",
- "Ranges": 42,
- "ASNs": 3,
- "LastFetch": "2026-07-09T12:00:00Z",
- "Error": ""
}
]
}| asn required | integer Example: 13335 Autonomous System Number to block |
curl -u "admin:pass" -X PUT \ "http://192.168.2.1/firewall/geo_block/asn/13335"
{- "Enabled": true,
- "DenyCountries": [
- "CN"
], - "DenyASNs": [
- {
- "ASN": 13335,
- "Name": "CLOUDFLARENET"
}
], - "Lists": [
], - "RefreshSeconds": 86400
}| asn required | integer Example: 13335 Autonomous System Number to unblock |
curl -u "admin:pass" -X DELETE \ "http://192.168.2.1/firewall/geo_block/asn/13335"
{- "Enabled": true,
- "DenyCountries": [
- "CN"
], - "DenyASNs": [
- {
- "ASN": 13335,
- "Name": "CLOUDFLARENET"
}
], - "Lists": [
], - "RefreshSeconds": 86400
}| cc required | string Example: CN Two-letter ISO 3166-1 alpha-2 country code |
curl -u "admin:pass" -X PUT \ "http://192.168.2.1/firewall/geo_block/country/CN"
{- "Enabled": true,
- "DenyCountries": [
- "CN"
], - "DenyASNs": [
- {
- "ASN": 13335,
- "Name": "CLOUDFLARENET"
}
], - "Lists": [
], - "RefreshSeconds": 86400
}| cc required | string Example: CN Two-letter ISO 3166-1 alpha-2 country code |
curl -u "admin:pass" -X DELETE \ "http://192.168.2.1/firewall/geo_block/country/CN"
{- "Enabled": true,
- "DenyCountries": [
- "CN"
], - "DenyASNs": [
- {
- "ASN": 13335,
- "Name": "CLOUDFLARENET"
}
], - "Lists": [
], - "RefreshSeconds": 86400
}FirewallBlockOutput
| DstIP | string |
| SrcIP | string |
| DstPort | string |
| Protocol | string/udp|tcp/ |
{- "DstIP": "1.2.3.4",
- "SrcIP": "0.0.0.0/24",
- "DstPort": "0-65535",
- "Protocol": "tcp"
}FirewallBlockOutput
| DstIP | string |
| SrcIP | string |
| DstPort | string |
| Protocol | string/udp|tcp/ |
{- "DstIP": "1.2.3.4",
- "SrcIP": "0.0.0.0/24",
- "DstPort": "0-65535",
- "Protocol": "tcp"
}curl -u "admin:pass" \ "http://192.168.2.1/iptraffic"
[- {
- "Interface": "wlan1",
- "Src": "192.168.2.100",
- "Dst": "192.168.2.102",
- "Packets": 1024,
- "Bytes": 4096
}
]Returns traffic information from the counter specified by the name parameter. Countermap can be one of incoming_traffic_lan | outgoing_traffic_lan | outgoing_traffic_wan | incoming_traffic_wan. See the accounting.sh NFT rules for additional information
| countermap required | string Example: incoming_traffic_lan Name of counter |
curl -u "admin:pass" \ "http://192.168.2.1/traffic/outgoing_traffic_lan"
[- {
- "IP": "192.168.2.1",
- "Packets": 7544,
- "Bytes": 824606
}
]Returns traffic information for all devices
curl -u "admin:pass" \ "http://192.168.2.1/traffic_history"
{- "192.168.2.11": {
- "LanIn": 11125256532,
- "LanOut": 292437928,
- "WanIn": 52664,
- "WanOut": 52664
}, - "192.168.2.12": {
- "LanIn": 11125256532,
- "LanOut": 292437928,
- "WanIn": 52664,
- "WanOut": 52664
}
}Traffic insights configuration object
| Enabled | boolean Whether traffic insights collection is enabled |
| RetentionDays | integer Number of days of hourly buckets to retain (1-90) |
{- "Enabled": true,
- "RetentionDays": 7
}{- "Enabled": true,
- "RetentionDays": 7
}| minutes | integer Example: minutes=1440 Length of the lookback window in minutes (defaults to 1440) |
curl -u "admin:pass" \ "http://192.168.2.1/traffic_insights/overview?minutes=1440"
{- "Start": "2026-07-08T00:00:00Z",
- "End": "2026-07-09T00:00:00Z",
- "TotalIn": 8388608,
- "TotalOut": 4194304,
- "Countries": [
- {
- "Country": "US",
- "BytesIn": 4194304,
- "BytesOut": 2097152,
- "Devices": [
- {
- "IP": "192.168.2.20",
- "BytesIn": 1048576,
- "BytesOut": 524288
}
], - "ASNs": [
- {
- "ASN": 15169,
- "Name": "GOOGLE",
- "Country": "US",
- "BytesIn": 2097152,
- "BytesOut": 1048576,
- "Devices": [
- {
- "IP": "192.168.2.20",
- "BytesIn": 1048576,
- "BytesOut": 524288
}
]
}
]
}
], - "ASNs": [
- {
- "ASN": 15169,
- "Name": "GOOGLE",
- "Country": "US",
- "BytesIn": 2097152,
- "BytesOut": 1048576,
- "Devices": [
- {
- "IP": "192.168.2.20",
- "BytesIn": 1048576,
- "BytesOut": 524288
}
]
}
], - "ContainerNets": [
- "172.17.0.0/16"
]
}| ip required | string Example: 192.168.2.20 IP address of the local device to report on |
| minutes | integer Example: minutes=1440 Length of the lookback window in minutes (defaults to 1440) |
curl -u "admin:pass" \ "http://192.168.2.1/traffic_insights/device/192.168.2.20?minutes=1440"
{- "IP": "192.168.2.20",
- "BytesIn": 1048576,
- "BytesOut": 524288,
- "Destinations": [
- {
- "IP": "142.250.72.14",
- "Domain": "www.google.com",
- "ASN": 15169,
- "ASNName": "GOOGLE",
- "Country": "US",
- "BytesIn": 65536,
- "BytesOut": 32768,
- "LastSeen": "2026-07-09T11:30:00Z"
}
]
}Returns current status for hostapd
| interface required | string Name of wireless interface |
curl -u "admin:pass" \ "http://192.168.2.1/hostapd/status"
{- "beacon_int": "100",
- "bss[0]": "wlan1",
- "bssid[0]": "00:c0:ca:33:11:22",
- "cac_time_left_seconds": "N/A",
- "cac_time_seconds": "0",
- "channel": "36",
- "dtim_period": "2",
- "edmg_channel": "0",
- "edmg_enable": "0",
- "freq": "5180",
- "ht_caps_info": "01ff",
- "ht_mcs_bitmask": "ffff0000000000000000",
- "ht_op_mode": "0x6",
- "ieee80211ac": "1",
- "ieee80211ax": "0",
- "ieee80211n": "1",
- "max_txpower": "23",
- "num_sta[0]": "6",
- "num_sta_ht40_intolerant": "0",
- "num_sta_ht_20_mhz": "2",
- "num_sta_ht_no_gf": "6",
- "num_sta_no_ht": "0",
- "num_sta_no_short_preamble": "6",
- "num_sta_no_short_slot_time": "6",
- "num_sta_non_erp": "0",
- "olbc": "0",
- "olbc_ht": "0",
- "phy": "phy1",
- "rx_vht_mcs_map": "fffa",
- "secondary_channel": "1",
- "ssid[0]": "test_ap",
- "state": "ENABLED",
- "supported_rates": "0c 12 18 24 30 48 60 6c",
- "tx_vht_mcs_map": "fffa",
- "vht_caps_info": "318001b0",
- "vht_oper_centr_freq_seg0_idx": "42",
- "vht_oper_centr_freq_seg1_idx": "0",
- "vht_oper_chwidth": "1"
}Returns current status for all stations
| interface required | string Name of wireless interface |
curl -u "admin:pass" \ "http://192.168.2.1/hostapd/all_stations"
{- "11:22:33:44:55:61": {
- "AKMSuiteSelector": "00-0f-ac-2",
- "aid": "3",
- "capability": "0x11",
- "connected_time": "4946",
- "dot11RSNAStatsSTAAddress": "11:22:33:44:55:61",
- "dot11RSNAStatsSelectedPairwiseCipher": "00-0f-ac-4",
- "dot11RSNAStatsTKIPLocalMICFailures": "0",
- "dot11RSNAStatsTKIPRemoteMICFailures": "0",
- "dot11RSNAStatsVersion": "1",
- "flags": "[AUTH][ASSOC][AUTHORIZED][WMM][HT]",
- "hostapdWPAPTKGroupState": "0",
- "hostapdWPAPTKState": "11",
- "ht_caps_info": "0x016e",
- "ht_mcs_bitmask": "ff000000000000000000",
- "inactive_msec": "1584",
- "listen_interval": "1",
- "rx_bytes": "126055",
- "rx_packets": "2394",
- "rx_rate_info": "60",
- "signal": "-85",
- "supported_rates": "8c 12 98 24 b0 48 60 6c",
- "timeout_next": "NULLFUNC POLL",
- "tx_bytes": "485584",
- "tx_packets": "1957",
- "tx_rate_info": "1200 mcs 5 shortGI",
- "vlan_id": "4247",
- "wpa": "2"
}, - "11:22:33:44:55:62": {
- "AKMSuiteSelector": "00-0f-ac-2",
- "aid": "3",
- "capability": "0x11",
- "connected_time": "4946",
- "dot11RSNAStatsSTAAddress": "11:22:33:44:55:61",
- "dot11RSNAStatsSelectedPairwiseCipher": "00-0f-ac-4",
- "dot11RSNAStatsTKIPLocalMICFailures": "0",
- "dot11RSNAStatsTKIPRemoteMICFailures": "0",
- "dot11RSNAStatsVersion": "1",
- "flags": "[AUTH][ASSOC][AUTHORIZED][WMM][HT]",
- "hostapdWPAPTKGroupState": "0",
- "hostapdWPAPTKState": "11",
- "ht_caps_info": "0x016e",
- "ht_mcs_bitmask": "ff000000000000000000",
- "inactive_msec": "1584",
- "listen_interval": "1",
- "rx_bytes": "126055",
- "rx_packets": "2394",
- "rx_rate_info": "60",
- "signal": "-85",
- "supported_rates": "8c 12 98 24 b0 48 60 6c",
- "timeout_next": "NULLFUNC POLL",
- "tx_bytes": "485584",
- "tx_packets": "1957",
- "tx_rate_info": "1200 mcs 5 shortGI",
- "vlan_id": "4247",
- "wpa": "2"
}
}Set hostapd configuration
| interface required | string Name of wireless interface |
Channel Parameters for WiFi
| Country_code | string 2-letter country code |
| Vht_capab | string Very High Throughput capabilities for 5ghz (802.11ac). Should be removed for 2.4ghz |
| Ht_capab | string High Throughput capabilities (802.11n) |
| Hw_mode | string/^(a/b/g)$/ a for 5ghz, b/g for 2.4ghz |
| Ieee80211ax | integer WiFi 6 support |
| He_su_beamformer | integer High Efficiency (WiFi 6) Single User Beamformer enable |
| He_su_beamformee | integer High Efficiency (WiFi 6) Single User Beamformee enable |
| He_mu_beamformer | integer High Efficiency (WiFi 6) Multiple User Beamformer enable |
| Ssid | string WiFi SSID Name |
| Channel | integer See the list of WLAN channels |
| Vht_oper_centr_freq_seg0_idx | integer |
| He_oper_centr_freq_seg0_idx | integer |
| Vht_oper_chwidth | integer |
| He_oper_chwidth | integer |
{- "Country_code": "US",
- "Vht_capab": "[RXLDPC][SHORT-GI-80][TX-STBC-2BY1][RX-STBC-1][MAX-A-MPDU-LEN-EXP3][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]",
- "Ht_capab": "[LDPC][HT40+][HT40-][GF][SHORT-GI-20][SHORT-GI-40][TX-STBC][RX-STBC1]",
- "Hw_mode": "a",
- "Ieee80211ax": 1,
- "He_su_beamformer": 1,
- "He_su_beamformee": 1,
- "He_mu_beamformer": 1,
- "Ssid": "8hzWANip",
- "Channel": 36,
- "Vht_oper_centr_freq_seg0_idx": 42,
- "He_oper_centr_freq_seg0_idx": 42,
- "Vht_oper_chwidth": 1,
- "He_oper_chwidth": 1
}Sets channel configuration
| interface required | string Name of wireless interface |
Channel Parameters for WiFi
| Mode | string/^(a|b|g)$/ g for 2.4Ghz, a for 5Ghz |
| Channel | integer See the list of WLAN channels |
| Bandwidth | integer Channel width in Mhz. One of 20, 40, 80, 160, or 8080 for 80+80 |
| HT_Enable | boolean 802.11n support - High Throughput |
| VHT_Enable | boolean 802.11ac support - Very High Throughput (WiFi 5) |
| HE_Enable | boolean 802.11ax support - High Effiency (WiFi 6) |
{- "Mode": "a",
- "Channel": 36,
- "Bandwidth": 80,
- "HT_Enable": true,
- "VHT_Enable": true,
- "HE_Enable": true
}{- "Vht_oper_centr_freq_seg0_idx": 42,
- "He_oper_centr_freq_seg0_idx": 42,
- "Vht_oper_chwidth": 1,
- "He_oper_chwidth": 1
}Enables an additional BSS (Basic Service Set) on the specified interface. This supports WPA1, and disabled isolation. Requires card support
| interface required | string Name of the network interface. |
| Ssid | string |
| Bssid | string |
| Wpa | string |
| WpaKeyMgmt | string |
| DisableIsolation | boolean |
{- "Ssid": "string",
- "Bssid": "string",
- "Wpa": "string",
- "WpaKeyMgmt": "string",
- "DisableIsolation": true
}Disables an additional BSS on the specified interface.
| interface required | string Name of the network interface. |
curl -u "admin:pass" -X DELETE \ "http://192.168.2.1/hostapd/eth0/enableExtraBSS"
SPR Tracks the state of interfaces to decide launching hostap
curl -u "admin:pass" \ "http://192.168.2.1/interfacesConfiguration"
[- {
- "Name": "wlan1",
- "Type": "AP",
- "Enabled": true
}
]Returns the current 802.11v fast-roaming configuration proxied from wifid
curl -u "admin:pass" \ "http://192.168.2.1/hostapd/roaming/config"
{- "DryRun": true,
- "PollIntervalSeconds": 15,
- "ObservationDelaySeconds": 20,
- "RSSIThresholdDBM": -70,
- "MinimumImprovementDBM": 5,
- "CooldownSeconds": 900,
- "MaxTransitionsPerHour": 4,
- "ExplorationRate": 0,
- "AllowedInterfaces": [ ]
}Validates and stores the 802.11v fast-roaming configuration
Fast-roaming configuration to store
| DryRun | boolean When true, recommend transitions without sending them |
| PollIntervalSeconds | integer Seconds between topology polls (5-300) |
| ObservationDelaySeconds | integer Seconds to wait before observing a transition outcome (5-180) |
| RSSIThresholdDBM | integer Only roam stations weaker than this RSSI in dBm (-100 to -30) |
| MinimumImprovementDBM | integer Minimum expected RSSI improvement in dBm to act (0-40) |
| CooldownSeconds | integer Per-station cooldown between transitions in seconds (30-86400) |
| MaxTransitionsPerHour | integer Maximum live transitions per hour across the router (1-100) |
| ExplorationRate | number <float> Probability of exploring a random candidate (0-1) |
| AllowedInterfaces | Array of strings Interfaces eligible as transition targets; empty means all |
{- "DryRun": true,
- "PollIntervalSeconds": 15,
- "ObservationDelaySeconds": 20,
- "RSSIThresholdDBM": -70,
- "MinimumImprovementDBM": 5,
- "CooldownSeconds": 900,
- "MaxTransitionsPerHour": 4,
- "ExplorationRate": 0,
- "AllowedInterfaces": [ ]
}{- "DryRun": true,
- "PollIntervalSeconds": 15,
- "ObservationDelaySeconds": 20,
- "RSSIThresholdDBM": -70,
- "MinimumImprovementDBM": 5,
- "CooldownSeconds": 900,
- "MaxTransitionsPerHour": 4,
- "ExplorationRate": 0,
- "AllowedInterfaces": [ ]
}Returns runtime status counters for the fast-roaming manager
curl -u "admin:pass" \ "http://192.168.2.1/hostapd/roaming/status"
{- "RoamingEnabled": true,
- "Config": {
- "DryRun": true,
- "PollIntervalSeconds": 15,
- "ObservationDelaySeconds": 20,
- "RSSIThresholdDBM": -70,
- "MinimumImprovementDBM": 5,
- "CooldownSeconds": 900,
- "MaxTransitionsPerHour": 4,
- "ExplorationRate": 0,
- "AllowedInterfaces": [ ]
}, - "HistoryCount": 12,
- "ModelArms": 8,
- "TransitionsActive": 0
}Returns recorded BSS transition attempts, newest first
curl -u "admin:pass" \ "http://192.168.2.1/hostapd/roaming/history"
[- {
- "ID": "1718000000000000000-1",
- "RequestedAt": "2026-07-09T12:00:00Z",
- "ObservedAt": "2026-07-09T12:00:20Z",
- "Origin": "auto",
- "MAC": "11:22:33:44:55:66",
- "SourceInterface": "wlan0",
- "TargetInterface": "wlan1",
- "SourceRSSI": -75,
- "PostRSSI": -55,
- "PostInterface": "wlan1",
- "DryRun": false,
- "State": "succeeded",
- "Reward": 45,
- "HostapdResponse": "OK",
- "Error": ""
}
]Returns the learned bandit model, keyed by device/interface/RSSI bucket
curl -u "admin:pass" \ "http://192.168.2.1/hostapd/roaming/model"
{- "property1": {
- "Count": 3,
- "Value": 42.5,
- "LastReward": 45,
- "UpdatedAt": "2026-07-09T12:00:20Z"
}, - "property2": {
- "Count": 3,
- "Value": 42.5,
- "LastReward": 45,
- "UpdatedAt": "2026-07-09T12:00:20Z"
}
}Computes center frequencies and channel widths without applying them
Channel Parameters for WiFi
| Mode | string/^(a|b|g)$/ g for 2.4Ghz, a for 5Ghz |
| Channel | integer See the list of WLAN channels |
| Bandwidth | integer Channel width in Mhz. One of 20, 40, 80, 160, or 8080 for 80+80 |
| HT_Enable | boolean 802.11n support - High Throughput |
| VHT_Enable | boolean 802.11ac support - Very High Throughput (WiFi 5) |
| HE_Enable | boolean 802.11ax support - High Effiency (WiFi 6) |
{- "Mode": "a",
- "Channel": 36,
- "Bandwidth": 80,
- "HT_Enable": true,
- "VHT_Enable": true,
- "HE_Enable": true
}{- "Vht_oper_centr_freq_seg0_idx": 42,
- "He_oper_centr_freq_seg0_idx": 42,
- "Vht_oper_chwidth": 1,
- "He_oper_chwidth": 1
}Sends an advisory 802.11v BSS transition for a station toward a target interface
| interface required | string Name of the source wireless interface |
BSS transition target for a station
| MAC | string Station MAC address to steer |
| TargetInterface | string Interface to steer the station toward |
{- "MAC": "11:22:33:44:55:66",
- "TargetInterface": "wlan1"
}Disassociates and deauthenticates a station from the interface
| interface required | string Name of wireless interface |
JSON string containing the station MAC to deauthenticate
Station MAC address
"11:22:33:44:55:66"Reports whether the interface is running in failsafe mode
| interface required | string Name of wireless interface |
curl -u "admin:pass" \ "http://192.168.2.1/hostapd/wlan0/failsafe"
"ok"Retrieves the current WPA supplicant configuration.
{- "WPAs": [
- {
- "Iface": "string",
- "Enabled": true,
- "Networks": [
- {
- "Disabled": true,
- "Password": "string",
- "SSID": "string",
- "KeyMgmt": "string",
- "Priority": "string",
- "BSSID": "string"
}
]
}
]
}Updates an existing WPA interface configuration or adds a new one.
| Iface | string |
| Enabled | boolean |
Array of objects (WPANetwork) |
{- "Iface": "string",
- "Enabled": true,
- "Networks": [
- {
- "Disabled": true,
- "Password": "string",
- "SSID": "string",
- "KeyMgmt": "string",
- "Priority": "string",
- "BSSID": "string"
}
]
}Updates an existing PPP interface configuration or adds a new one.
| Iface | string |
| PPPIface | string |
| Enabled | boolean |
| Username | string |
| Secret | string |
| VLAN | string or null |
| MTU | string or null |
{- "Iface": "string",
- "PPPIface": "string",
- "Enabled": true,
- "Username": "string",
- "Secret": "string",
- "VLAN": "string",
- "MTU": "string"
}Updates the IP configuration of a network interface.
| Name | string |
| Enabled | boolean |
| DisableDHCP | boolean or null |
| IP | string or null |
| Router | string or null |
| VLAN | string or null |
{- "Name": "string",
- "Enabled": true,
- "DisableDHCP": true,
- "IP": "string",
- "Router": "string",
- "VLAN": "string"
}Updates the configuration of a LAN network interface.
| Name | string Interface name on system |
| Type | string Enum: "AP" "Uplink" "Downlink" "Other" |
| Subtype | string |
| Enabled | boolean |
{- "Name": "string",
- "Type": "AP",
- "Subtype": "string",
- "Enabled": true
}Set an interface as a VLAN trunk, enabling or disabling it.
| interface required | string Name of the network interface. |
| state required | string Enum: "enable" "disable" State of the VLAN trunk on the interface (enable or disable). |
# Example to enable VLAN trunk on eth0 curl -u "admin:pass" -X PUT \ "http://192.168.2.1/link/vlan/eth0/enable" # Example to disable VLAN trunk on eth0 curl -u "admin:pass" -X PUT \ "http://192.168.2.1/link/vlan/eth0/disable"
Interface IP configuration to apply
| Name | string Interface name on system |
| Type | string Interface type |
| Enabled | boolean Whether the interface is enabled |
| IP | string Primary IP or CIDR for the interface |
| Router | string Gateway IP for the interface |
| VLAN | string VLAN tag for the interface |
Array of objects (AdditionalIP) Additional IPs bound to the interface |
{- "Name": "eth1",
- "Type": "Downlink",
- "Enabled": true,
- "IP": "192.168.2.1/24",
- "Router": "192.168.2.1",
- "VLAN": "10",
- "AdditionalIPs": [
- {
- "IP": "192.168.5.1/24",
- "Router": "192.168.5.1"
}
]
}Get latest tag from docker specified by the container parameter. If no container is specified version is fetched for superd
| container | string container to get version for |
curl -u "admin:pass" \ "http://192.168.2.1/version"
"0.1.23"Returns the output of journalctl in json format
curl -u "admin:pass" \ "http://192.168.2.1/logs"
[- {
- "CONTAINER_NAME": "superapi",
- "MESSAGE": "192.168.2.101:1234 GET /logs",
- "__REALTIME_TIMESTAMP": 1651066188615770
}
]| name required | string Example: uptime Info field to retrieve (uptime, dockernetworks, docker, hostname, ss) |
curl -u "admin:pass" http://192.168.2.1/info/uptime
{ }| name required | string Example: hostname Info field to set (currently only hostname is supported) |
New value for the named system info field (currently hostname)
"my-router"| service | string Example: service=mesh Service name to inspect |
| compose_file | string Example: compose_file=/configs/plugins/mesh/docker-compose.yml Compose file path to inspect |
curl -u "admin:pass" "http://192.168.2.1/dockerPS?service=mesh"
"CONTAINER ID IMAGE STATUS"Returns an object with the current SPR version and Channel, Version settings
curl -u "admin:pass" \ "http://192.168.2.1/release"
{- "CustomChannel": "-dev",
- "CustomVersion": "0.1.2",
- "Current": "0.1.2-dev"
}Set a custom Channel, Version to update into
| CustomChannel | string |
| CustomVersion | string |
| Current | string |
{- "CustomChannel": "-dev",
- "CustomVersion": "0.1.3"
}Returns a list of tags available to update into
| container required | string Example: container=super_superd Container name |
curl -u "admin:pass" \ "http://192.168.2.1/releaseChannels"
[- "latest",
- "0.1.23",
- "0.1.23-dev"
]Release channel and version settings to apply
| CustomChannel | string Custom release channel to track |
| CustomVersion | string Pinned custom version to install |
| Current | string Currently running release version |
{- "CustomChannel": "main",
- "CustomVersion": "0.3.6",
- "Current": "0.3.5"
}curl -u "admin:pass" \ "http://192.168.2.1/plugins"
[- {
- "Name": "dns-block",
- "URI": "dns/block",
- "UnixPath": "/state/dns/dns_block_plugin",
- "Enabled": true,
- "Plus": false,
- "ComposeFilePath": "plugins/plugin/docker-compose.yml",
- "HasUI": true,
- "SandboxedUI": true,
- "InstallTokenPath": "/config/plugins/dns-block/install-token",
- "ScopedPaths": [
- "/config/plugins/dns-block",
- "/state/plugins/dns-block"
]
}
]Add or update a plugin specified by the name parameter
| name required | string Example: dns-block plugin name |
PluginEntry to be added or updated
| Name | string Plugin name |
| URI | string Plugin URI |
| UnixPath | string Plugin path for unix socket |
| Enabled | boolean Plugin state |
| Plus | boolean Indicates if this is a PLUS plugin |
| GitURL | string Git repository URL for the plugin |
| ComposeFilePath | string Relative path to docker compose file |
| HasUI | boolean Indicates if the plugin has a user interface |
| SandboxedUI | boolean Indicates if the plugin UI is sandboxed |
| InstallTokenPath | string Path to the installation token |
| ScopedPaths | Array of strings List of scoped paths for the plugin |
{- "Name": "dns-block",
- "URI": "dns/block",
- "UnixPath": "/state/dns/dns_block_plugin",
- "Enabled": true,
- "Plus": false,
- "ComposeFilePath": "plugins/plugin/docker-compose.yml",
- "HasUI": true,
- "SandboxedUI": true,
- "InstallTokenPath": "/config/plugins/dns-block/install-token",
- "ScopedPaths": [
- "/config/plugins/dns-block",
- "/state/plugins/dns-block"
]
}Updates the permit list of docker compose files that can be launched from disk
[- "string"
]PluginEntry to be added or updated
| Name | string Plugin name |
| URI | string Plugin URI |
| UnixPath | string Plugin path for unix socket |
| Enabled | boolean Plugin state |
| Plus | boolean Indicates if this is a PLUS plugin |
| GitURL | string Git repository URL for the plugin |
| ComposeFilePath | string Relative path to docker compose file |
| HasUI | boolean Indicates if the plugin has a user interface |
| SandboxedUI | boolean Indicates if the plugin UI is sandboxed |
| InstallTokenPath | string Path to the installation token |
| ScopedPaths | Array of strings List of scoped paths for the plugin |
{- "Name": "dns-block",
- "URI": "dns/block",
- "UnixPath": "/state/dns/dns_block_plugin",
- "Enabled": true,
- "Plus": false,
- "ComposeFilePath": "plugins/plugin/docker-compose.yml",
- "HasUI": true,
- "SandboxedUI": true,
- "InstallTokenPath": "/config/plugins/dns-block/install-token",
- "ScopedPaths": [
- "/config/plugins/dns-block",
- "/state/plugins/dns-block"
]
}[- {
- "Name": "dns-block",
- "URI": "dns/block",
- "UnixPath": "/state/dns/dns_block_plugin",
- "Enabled": true,
- "Plus": false,
- "ComposeFilePath": "plugins/plugin/docker-compose.yml",
- "HasUI": true,
- "SandboxedUI": true,
- "InstallTokenPath": "/config/plugins/dns-block/install-token",
- "ScopedPaths": [
- "/config/plugins/dns-block",
- "/state/plugins/dns-block"
]
}
]Git URL string of the user plugin
Git URL of the plugin to download
{- "Name": "dns-block",
- "URI": "dns/block",
- "UnixPath": "/state/dns/dns_block_plugin",
- "Enabled": true,
- "Plus": false,
- "ComposeFilePath": "plugins/plugin/docker-compose.yml",
- "HasUI": true,
- "SandboxedUI": true,
- "InstallTokenPath": "/config/plugins/dns-block/install-token",
- "ScopedPaths": [
- "/config/plugins/dns-block",
- "/state/plugins/dns-block"
]
}| compose_file | string Example: compose_file=/configs/plugins/mesh/docker-compose.yml Path to the plugin compose file to attest (compose_file or service required) |
| service | string Example: service=mesh Service name to attest (compose_file or service required) |
| force | string Example: force=1 Force re-attestation when set to a non-empty value |
curl -u "admin:pass" "http://192.168.2.1/pluginAttest?service=mesh"
{ }Get an array of all tokens
curl -u "admin:pass" -H "X-JWT-OTP:..." \ "http://192.168.2.1/tokens"
[- {
- "Name": "TestToken",
- "Token": "dG9rbnRva250b2tudG9rbnRva250b2tudG9rbnRva24K",
- "ScopedPaths": [
- "wifi"
], - "Expire": 1656440879
}
]Create a new token. If Expire is 0 or undefined the Token will never expire
| Expire | integer |
| ScopedPaths | Array of strings |
{- "Expire": 1656440879,
- "ScopedPaths": [
- "/status",
- "/docker/info"
]
}{- "Name": "TestToken",
- "Token": "dG9rbnRva250b2tudG9rbnRva250b2tudG9rbnRva24K",
- "ScopedPaths": [
- "wifi"
], - "Expire": 1656440879
}curl -X GET "http://192.168.2.1/alerts"
[- {
- "TopicPrefix": "string",
- "MatchAnyOne": true,
- "InvertRule": true,
- "Conditions": [
- {
- "JPath": "string"
}
], - "Actions": [
- {
- "SendNotification": true,
- "StoreAlert": true,
- "StoreTopicSuffix": "string",
- "MessageTitle": "string",
- "MessageBody": "string",
- "NotificationType": "string",
- "ActionType": "string",
- "GrabEvent": true,
- "GrabValues": true,
- "GrabFields": [
- "string"
]
}
], - "Name": "string",
- "Disabled": true,
- "RuleId": "string"
}
]If an alert setting does not exist, it will be created, otherwise updated
AlertSetting object that needs to be added
| TopicPrefix required | string |
| MatchAnyOne | boolean |
| InvertRule | boolean |
Array of objects (ConditionEntry) | |
Array of objects (ActionConfig) | |
| Name | string |
| Disabled | boolean |
| RuleId | string |
{- "TopicPrefix": "string",
- "MatchAnyOne": true,
- "InvertRule": true,
- "Conditions": [
- {
- "JPath": "string"
}
], - "Actions": [
- {
- "SendNotification": true,
- "StoreAlert": true,
- "StoreTopicSuffix": "string",
- "MessageTitle": "string",
- "MessageBody": "string",
- "NotificationType": "string",
- "ActionType": "string",
- "GrabEvent": true,
- "GrabValues": true,
- "GrabFields": [
- "string"
]
}
], - "Name": "string",
- "Disabled": true,
- "RuleId": "string"
}Update an alert setting at a specific index. If the alert setting does not exist at this index, it will be created. Fields are optional.
| index required | integer Example: 1 |
AlertSetting object that needs to be added
| TopicPrefix required | string |
| MatchAnyOne | boolean |
| InvertRule | boolean |
Array of objects (ConditionEntry) | |
Array of objects (ActionConfig) | |
| Name | string |
| Disabled | boolean |
| RuleId | string |
{- "TopicPrefix": "string",
- "MatchAnyOne": true,
- "InvertRule": true,
- "Conditions": [
- {
- "JPath": "string"
}
], - "Actions": [
- {
- "SendNotification": true,
- "StoreAlert": true,
- "StoreTopicSuffix": "string",
- "MessageTitle": "string",
- "MessageBody": "string",
- "NotificationType": "string",
- "ActionType": "string",
- "GrabEvent": true,
- "GrabValues": true,
- "GrabFields": [
- "string"
]
}
], - "Name": "string",
- "Disabled": true,
- "RuleId": "string"
}Mobile alert proxy settings object
| Disabled | boolean When true, the mobile alert proxy is disabled |
| APNSDomain | string Domain of the APNS proxy that relays notifications |
{- "Disabled": false,
- "APNSDomain": "apns.supernetworks.org"
}{- "Disabled": false,
- "APNSDomain": "apns.supernetworks.org"
}curl -u "admin:pass" \ "http://192.168.2.1/alerts_register_ios"
[- {
- "DeviceId": "FCDBD8EF-62FC-4ECB-B2F5-92C9E79AC7F9",
- "DeviceToken": "aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899",
- "PublicKey": "MFkwEwYHKoZIzj0CAQYIK...",
- "LastActive": "2024-03-13T23:43:39Z"
}
]Alert device object
| DeviceId | string Mobile device identifier (36 char UUID for iOS) |
| DeviceToken | string APNS device token (64 hex characters) |
| PublicKey | string Device public key used to encrypt alert payloads |
| LastActive | string <date-time> Timestamp the device was last active |
{- "DeviceId": "FCDBD8EF-62FC-4ECB-B2F5-92C9E79AC7F9",
- "DeviceToken": "aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899",
- "PublicKey": "MFkwEwYHKoZIzj0CAQYIK...",
- "LastActive": "2024-03-13T23:43:39Z"
}[- {
- "DeviceId": "FCDBD8EF-62FC-4ECB-B2F5-92C9E79AC7F9",
- "DeviceToken": "aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899",
- "PublicKey": "MFkwEwYHKoZIzj0CAQYIK...",
- "LastActive": "2024-03-13T23:43:39Z"
}
]Alert device object
| DeviceId | string Mobile device identifier (36 char UUID for iOS) |
| DeviceToken | string APNS device token (64 hex characters) |
| PublicKey | string Device public key used to encrypt alert payloads |
| LastActive | string <date-time> Timestamp the device was last active |
{- "DeviceId": "FCDBD8EF-62FC-4ECB-B2F5-92C9E79AC7F9",
- "DeviceToken": "aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899",
- "PublicKey": "MFkwEwYHKoZIzj0CAQYIK...",
- "LastActive": "2024-03-13T23:43:39Z"
}[- {
- "DeviceId": "FCDBD8EF-62FC-4ECB-B2F5-92C9E79AC7F9",
- "DeviceToken": "aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899",
- "PublicKey": "MFkwEwYHKoZIzj0CAQYIK...",
- "LastActive": "2024-03-13T23:43:39Z"
}
]| deviceToken required | string Example: aabbccddeeff00112233445566778899aabbccddeeff00112233445566778899 APNS device token (64 hex characters) |
APNS alert to send
| title | string Alert title |
| body | string Alert body text |
{- "title": "SPR Alert",
- "body": "A new device joined the network"
}{- "title": "SPR Alert",
- "body": "A new device joined the network"
}Updates an OTP user with the given details. If already registered, a valid code is required
| Name | string |
| Code | string |
| UpdateAlwaysOn | boolean |
| AlwaysOn | boolean |
{- "Name": "string",
- "Code": "string",
- "UpdateAlwaysOn": true,
- "AlwaysOn": true
}Deletes an OTP user. Valid code required
| Name | string |
| Code | string |
| UpdateAlwaysOn | boolean |
| AlwaysOn | boolean |
{- "Name": "string",
- "Code": "string",
- "UpdateAlwaysOn": true,
- "AlwaysOn": true
}Validates the provided OTP user details and generates the X-JWT-OTP token
| Name | string |
| Code | string |
| UpdateAlwaysOn | boolean |
| AlwaysOn | boolean |
{- "Name": "string",
- "Code": "string",
- "UpdateAlwaysOn": true,
- "AlwaysOn": true
}"string"curl -H "Authorization: Bearer [token]" -H "X-JWT-Token: [jwt-token]" \ "http://192.168.2.1/otp_status"
{- "State": "string",
- "AlwaysOn": true
}Start a PLUS extension. Currently this is the pfw plugin
| name | string Example: name=pfw Name of plus extension |
[- {
- "Conditions": {
- "Prefix": "drop:input",
- "Protocol": "tcp",
- "DstIP": "1.1.1.1",
- "DstPort": 80,
- "SrcIP": "192.168.2.10",
- "SrcPort": 1234
}, - "Notification": true
}
]Stop a PLUS extension. Currently this is the pfw plugin
| name | string Example: name=pfw Name of plus extension |
[- {
- "Conditions": {
- "Prefix": "drop:input",
- "Protocol": "tcp",
- "DstIP": "1.1.1.1",
- "DstPort": 80,
- "SrcIP": "192.168.2.10",
- "SrcPort": 1234
}, - "Notification": true
}
]curl -u "admin:pass" \ "http://192.168.2.1/wan/status"
[- {
- "Iface": "eth0",
- "Up": true,
- "Active": true,
- "Gateway": "192.168.1.1",
- "LatencyMs": 12.4,
- "JitterMs": 1.8,
- "LossPct": 0,
- "LastChange": 1720000000,
- "TotalOutages": 2,
- "Downtime24h": 45
}
]curl -u "admin:pass" \ "http://192.168.2.1/wan/config"
{- "Enabled": true,
- "IntervalSeconds": 5,
- "ProbeTargets": [
- "1.1.1.1"
], - "FailThreshold": 4,
- "RecoverThreshold": 3,
- "FailoverEnabled": true,
}WanHealthConfig object that needs to be updated
| Enabled | boolean Whether WAN health monitoring is enabled |
| IntervalSeconds | integer Probe interval in seconds (2-60) |
| ProbeTargets | Array of strings List of IPv4 addresses to probe via ICMP |
| FailThreshold | integer Consecutive probe failures before marking an uplink down (1-60) |
| RecoverThreshold | integer Consecutive probe successes before marking an uplink up (1-60) |
| FailoverEnabled | boolean Whether to remove a failed uplink from load balancing |
| SpeedTestURL | string HTTP(S) URL used for downlink speed tests |
{- "Enabled": true,
- "IntervalSeconds": 5,
- "ProbeTargets": [
- "1.1.1.1"
], - "FailThreshold": 4,
- "RecoverThreshold": 3,
- "FailoverEnabled": true,
}{- "Enabled": true,
- "IntervalSeconds": 5,
- "ProbeTargets": [
- "1.1.1.1"
], - "FailThreshold": 4,
- "RecoverThreshold": 3,
- "FailoverEnabled": true,
}| interface required | string Example: eth0 Uplink interface name |
| scale | string Example: scale=minutes Sample resolution, either minutes or hours |
| count | integer Example: count=60 Maximum number of samples to return |
curl -u "admin:pass" \ "http://192.168.2.1/wan/history/eth0?scale=minutes&count=60"
[- {
- "Time": 1720000000,
- "LatencyMs": 12.4,
- "JitterMs": 1.8,
- "LossPct": 0,
- "Up": true
}
]curl -u "admin:pass" \ "http://192.168.2.1/wan/speedtest"
[- {
- "Iface": "eth0",
- "Time": 1720000000,
- "DownMbps": 235.6,
- "Seconds": 1.14,
- "Bytes": 33554432,
- "Error": "no data transferred"
}
]| interface required | string Example: eth0 Uplink interface name to test |
curl -u "admin:pass" -X PUT \ "http://192.168.2.1/wan/speedtest/eth0"
{- "Iface": "eth0",
- "Time": 1720000000,
- "DownMbps": 235.6,
- "Seconds": 1.14,
- "Bytes": 33554432,
- "Error": "no data transferred"
}curl -u "admin:pass" \ "http://192.168.2.1/parentalControls/personas"
[- {
- "Name": "kids",
- "Tag": "persona:kids",
- "Description": "Children devices",
- "DailyLimitMinutes": 120,
- "Schedules": [
- {
- "Days": [
- 0,
- 1,
- 1,
- 1,
- 1,
- 1,
- 0
], - "Start": "21:00",
- "End": "07:00"
}
], - "DNSFamily": true,
- "Disabled": false
}
]Persona object
| Name | string Unique persona name |
| Tag | string Device tag bound to the persona; must start with "persona:" (defaults to persona:Name) |
| Description | string Human-readable description of the persona |
| DailyLimitMinutes | integer Daily internet time budget in minutes; 0 disables the limit |
Array of objects (TimeWindow) Recurring time windows during which internet access is blocked | |
| DNSFamily | boolean Whether to apply family-safe DNS filtering to the persona |
| Disabled | boolean Whether enforcement for this persona is disabled |
{- "Name": "kids",
- "Tag": "persona:kids",
- "Description": "Children devices",
- "DailyLimitMinutes": 120,
- "Schedules": [
- {
- "Days": [
- 0,
- 1,
- 1,
- 1,
- 1,
- 1,
- 0
], - "Start": "21:00",
- "End": "07:00"
}
], - "DNSFamily": true,
- "Disabled": false
}[- {
- "Name": "kids",
- "Tag": "persona:kids",
- "Description": "Children devices",
- "DailyLimitMinutes": 120,
- "Schedules": [
- {
- "Days": [
- 0,
- 1,
- 1,
- 1,
- 1,
- 1,
- 0
], - "Start": "21:00",
- "End": "07:00"
}
], - "DNSFamily": true,
- "Disabled": false
}
]Persona object
| Name | string Unique persona name |
| Tag | string Device tag bound to the persona; must start with "persona:" (defaults to persona:Name) |
| Description | string Human-readable description of the persona |
| DailyLimitMinutes | integer Daily internet time budget in minutes; 0 disables the limit |
Array of objects (TimeWindow) Recurring time windows during which internet access is blocked | |
| DNSFamily | boolean Whether to apply family-safe DNS filtering to the persona |
| Disabled | boolean Whether enforcement for this persona is disabled |
{- "Name": "kids",
- "Tag": "persona:kids",
- "Description": "Children devices",
- "DailyLimitMinutes": 120,
- "Schedules": [
- {
- "Days": [
- 0,
- 1,
- 1,
- 1,
- 1,
- 1,
- 0
], - "Start": "21:00",
- "End": "07:00"
}
], - "DNSFamily": true,
- "Disabled": false
}[- {
- "Name": "kids",
- "Tag": "persona:kids",
- "Description": "Children devices",
- "DailyLimitMinutes": 120,
- "Schedules": [
- {
- "Days": [
- 0,
- 1,
- 1,
- 1,
- 1,
- 1,
- 0
], - "Start": "21:00",
- "End": "07:00"
}
], - "DNSFamily": true,
- "Disabled": false
}
]Persona tag and duration in minutes
| Tag | string Persona tag or persona name to target |
| Minutes | integer Duration in minutes; 0 or less clears the override |
{- "Tag": "persona:kids",
- "Minutes": 30
}{- "Date": "2026-07-09",
- "UsedMinutes": {
- "persona:kids": 45
}, - "PauseUntil": {
- "persona:kids": 1752096000
}, - "GrantUntil": {
- "persona:kids": 1752096000
}
}Persona tag and duration in minutes
| Tag | string Persona tag or persona name to target |
| Minutes | integer Duration in minutes; 0 or less clears the override |
{- "Tag": "persona:kids",
- "Minutes": 30
}{- "Date": "2026-07-09",
- "UsedMinutes": {
- "persona:kids": 45
}, - "PauseUntil": {
- "persona:kids": 1752096000
}, - "GrantUntil": {
- "persona:kids": 1752096000
}
}Persona tag to reset
| Tag | string Persona tag or persona name to reset |
{- "Tag": "persona:kids"
}{- "Date": "2026-07-09",
- "UsedMinutes": {
- "persona:kids": 45
}, - "PauseUntil": {
- "persona:kids": 1752096000
}, - "GrantUntil": {
- "persona:kids": 1752096000
}
}curl -u "admin:pass" \ "http://192.168.2.1/customThemes"
[- {
- "id": "custom-ocean",
- "name": "Ocean",
- "spec": {
- "colorMode": "dark",
- "accent": "#3b82f6",
- "background": "#0b1220",
- "card": "#111827",
- "text": "#e5e7eb"
}
}
]Array of custom theme objects to store
| id | string Unique theme identifier matching ^custom-[a-z0-9-]{1,64}$ |
| name | string Human-readable theme name (1-64 characters) |
object (CustomThemeSpec) |
[- {
- "id": "custom-ocean",
- "name": "Ocean",
- "spec": {
- "colorMode": "dark",
- "accent": "#3b82f6",
- "background": "#0b1220",
- "card": "#111827",
- "text": "#e5e7eb"
}
}
][- {
- "id": "custom-ocean",
- "name": "Ocean",
- "spec": {
- "colorMode": "dark",
- "accent": "#3b82f6",
- "background": "#0b1220",
- "card": "#111827",
- "text": "#e5e7eb"
}
}
]Add domain to be blocked/permitted by DNS
DNSDomainOverride object that needs to be added
| Type | string type of override (permit or block) |
| Domain | string domain name to override |
| ResultIP | string/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/ ip to return |
| ClientIP | string/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/ target to apply to, '*' for all |
| Expiration | integer if non zero has unix time for when the entry should disappear |
{- "Type": "permit",
- "Domain": "example.com",
- "ResultIP": "1.2.3.4",
- "ClientIP": "192.168.2.102",
- "Expiration": 0
}Delete domain to be blocked/permitted by DNS
DNSDomainOverride object that needs to be added
| Type | string type of override (permit or block) |
| Domain | string domain name to override |
| ResultIP | string/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/ ip to return |
| ClientIP | string/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/ target to apply to, '*' for all |
| Expiration | integer if non zero has unix time for when the entry should disappear |
{- "Type": "permit",
- "Domain": "example.com",
- "ResultIP": "1.2.3.4",
- "ClientIP": "192.168.2.102",
- "Expiration": 0
}curl -u "admin:pass" \ "http://192.168.2.1/plugins/dns/block/blocklist"
[
]curl -u "admin:pass" \ "http://192.168.2.1/plugins/dns/log/config"
[- {
- "HostPrivacyIPList": [
- "192.168.1.10"
]
}, - {
- "DomainIgnoreList": [
- "asdf.com",
- "asdf2.com",
- "test.com."
]
}
]| ip required | string Example: 1.1.1.1 ip address |
curl -u "admin:pass" \ "http://192.168.2.1/plugins/dns/log/history/192.168.1.10"
[- {
- "Q": [
- {
- "Name": "supernetworks.org.",
- "Qtype": 1,
- "Qclass": 1
}
], - "A": [
- {
- "Hdr": {
- "Name": "supernetworks.org.",
- "Rrtype": 1,
- "Class": 1,
- "Ttl": 30,
- "Rdlength": 4
}, - "A": "172.67.71.52"
}, - {
- "Hdr": {
- "Name": "supernetworks.org.",
- "Rrtype": 1,
- "Class": 1,
- "Ttl": 30,
- "Rdlength": 4
}, - "A": "104.26.7.38"
}, - {
- "Hdr": {
- "Name": "supernetworks.org.",
- "Rrtype": 1,
- "Class": 1,
- "Ttl": 30,
- "Rdlength": 4
}, - "A": "104.26.6.38"
}
], - "Type": "NOERROR",
- "FirstName": "supernetworks.org.",
- "FirstAnswer": "172.67.71.52",
- "Local": "[::]:53",
- "Remote": "127.0.0.1:60237",
- "Timestamp": "2022-03-28T21:47:49.563958-07:00"
}
]curl -u "admin:pass" \ "http://192.168.2.1/plugins/wireguard/peers"
[- {
- "PublicKey": "7SdFRh8o76RjUn/y4c7cQgCcCXA85s47/gVAdem3bBI=",
- "AllowedIPs": "192.168.3.3/32",
- "Endpoint": "192.168.2.1:51280",
- "PresharedKey": "w9bfMAfqRnLjnlHofX+JSzaRDADrW1tvyW1UWzXJjrg=",
- "PersistentKeepalive": 25
}
]Creates a new peer
Device object
| PublicKey | string Base64 public key |
| AllowedIPs | string Allowed IP address |
| Endpoint | string Endpoint to connect to |
| PresharedKey | any Preshared key |
| PersistentKeepalive | integer Keepalive timeout |
{- "PublicKey": "7SdFRh8o76RjUn/y4c7cQgCcCXA85s47/gVAdem3bBI=",
- "AllowedIPs": "192.168.3.3/32",
- "Endpoint": "192.168.2.1:51280",
- "PresharedKey": "w9bfMAfqRnLjnlHofX+JSzaRDADrW1tvyW1UWzXJjrg=",
- "PersistentKeepalive": 25
}{- "Interface": {
- "PrivateKey": "6KVVbcmXanU/6mByHy17eNO9DXe9BQJWOyaA204JYH4=",
- "Address": "192.168.3.3/24",
- "DNS": "1.1.1.1"
}, - "Peer": {
- "PublicKey": "7SdFRh8o76RjUn/y4c7cQgCcCXA85s47/gVAdem3bBI=",
- "AllowedIPs": "192.168.3.3/32",
- "Endpoint": "192.168.2.1:51280",
- "PresharedKey": "w9bfMAfqRnLjnlHofX+JSzaRDADrW1tvyW1UWzXJjrg=",
- "PersistentKeepalive": 25
}
}curl -u "admin:pass" \ "http://192.168.2.1/plugins/wireguard/config"
"[Interface]\nAddress = 192.168.3.1/24\nListenPort = 51280\nPrivateKey = 6KVVbcmXanU/6mByHy17eNO9DXe9BQJWOyaA204JYH4=\n\n[Peer]\nPublicKey = 7SdFRh8o76RjUn/y4c7cQgCcCXA85s47/gVAdem3bBI=\nPresharedKey = w9bfMAfqRnLjnlHofX+JSzaRDADrW1tvyW1UWzXJjrg=\nAllowedIPs = 192.168.3.2/32\n"curl -u "admin:pass" \ "http://192.168.2.1/plugins/wireguard/status"
{- "wg0": {
- "privateKey": "6KVVbcmXanU/6mByHy17eNO9DXe9BQJWOyaA204JYH4=",
- "publicKey": "7SdFRh8o76RjUn/y4c7cQgCcCXA85s47/gVAdem3bBI=",
- "listenPort": "51280,",
- "peers": {
- "HvtqvLJ1F33eHmR5Yk9PLZfTHg7w6sazPZtZi9u8pBQ=": {
- "presharedKey": "w9bfMAfqRnLjnlHofX+JSzaRDADrW1tvyW1UWzXJjrg=",
- "allowedIps": [
- "192.168.3.2/32"
]
}
}
}
}Get ASN information for IP address
| ips required | string Example: 1.1.1.1,2.2.2.2 ip address list, separated by , |
curl -u "admin:pass" \ "http://192.168.2.1/plugins/lookup/asn/1.1.1.1"
{- "IP": "1.1.1.1",
- "ASN": 13335,
- "Name": "CLOUDFLARENET",
- "Country": "US"
}Get ASN information for IPs separated by ,
| ips required | string Example: 1.1.1.1,2.2.2.2 ip address list, separated by , |
curl -u "admin:pass" \ "http://192.168.2.1/plugins/lookup/asns/1.1.1.1,8.8.8.8"
[- {
- "IP": "1.1.1.1",
- "ASN": 13335,
- "Name": "CLOUDFLARENET",
- "Country": "US"
}
]Get OUI vendor information for MAC address
| mac required | string Example: 11:22:33:44:55:66 MAC address |
curl -u "admin:pass" \ "http://192.168.2.1/plugins/lookup/oui/00:11:22:33:44:55"
{- "MAC": "00:11:22:33:44:66",
- "Vendor": "CIMSYS"
}Get OUI vendor information for MACs separated by ,
| macs required | string Example: 00:11:22:33:44:66 MAC address list separated by , |
curl -u "admin:pass" \ "http://192.168.2.1/plugins/lookup/ouis/00:11:22:33:44:66"
[- {
- "MAC": "00:11:22:33:44:66",
- "Vendor": "CIMSYS"
}
]Returns the dyndns configuration
curl -u "admin:pass" \ "http://192.168.2.1/plugins/dyndns/config"
{- "Provider": "Cloudflare",
- "Password": "stringypassword",
- "LoginToken": "logintoken++",
- "IpType": "IPv4",
- "Interval": 300,
- "Socks5Proxy": "string",
- "Resolver": "8.8.8.8",
- "RunOnce": true,
- "Domains": [
- {
- "DomainName": "supernetworks.org",
- "SubDomains": [
- "dyndns"
]
}
]
}Dyndns Configuration. See godns for details
| Provider | string |
string | |
| Password | string |
| LoginToken | string |
| IpUrl | string |
| Ipv6Url | string |
| IpType | string |
| Interval | integer How many seconds to wait before checking for an update |
| Socks5Proxy | string socks5 proxy to use |
| Resolver | string DNS Resolver to use |
| RunOnce | boolean Run once and exit (note always set to true) |
Array of objects (GodyndnsDomain) |
{- "Provider": "Cloudflare",
- "Password": "stringypassword",
- "LoginToken": "logintoken++",
- "IpType": "IPv4",
- "Interval": 300,
- "Socks5Proxy": "string",
- "Resolver": "8.8.8.8",
- "RunOnce": true,
- "Domains": [
- {
- "DomainName": "supernetworks.org",
- "SubDomains": [
- "dyndns"
]
}
]
}Retrieves the current mesh network configuration
curl -u "admin:pass" \ "http://192.168.2.1/plugins/mesh/config"
{- "ParentCredentials": {
- "ParentIP": "string",
- "ParentAPIToken": "string",
- "ParentCA": "string"
}, - "LeafRouters": [
- {
- "APIToken": "string",
- "IP": "string",
- "TLSCA": "string"
}
]
}Retrieves a list of all leaf routers the main router has configured
curl -u "admin:pass" \ "http://192.168.2.1/plugins/mesh/leafRouters"
[- {
- "APIToken": "string",
- "IP": "string",
- "TLSCA": "string"
}
]Adds a new leaf router or updates an existing one
| APIToken | string |
| IP | string |
| TLSCA | string This field should be left empty when adding or updating a leaf router. |
{- "APIToken": "string",
- "IP": "string",
- "TLSCA": "string"
}Removes a leaf router from the main router's mesh network
| APIToken | string |
| IP | string |
| TLSCA | string This field should be left empty when adding or updating a leaf router. |
{- "APIToken": "string",
- "IP": "string",
- "TLSCA": "string"
}Endpoint for mesh nodes to notify the main router/AP about a new station connection to the mesh network
| Event | string Type of event (e.g., "connect" or "disconnect") |
| Iface | string Network interface on the mesh node where the event occurred |
| Mac | string MAC address of the station |
| Router | string IP address of the mesh node reporting the event |
{- "Event": "string",
- "Iface": "string",
- "Mac": "string",
- "Router": "string"
}Endpoint for mesh nodes to notify the main router/AP about a failed station connection attempt
| Type | string Type of failure event (e.g., "connection_failure") |
| MAC | string MAC address of the station that failed to connect |
| Reason | string Reason for the connection failure |
| Status | string Status of the connection attempt (e.g., "failure") |
| Router | string IP address of the mesh node reporting the failure |
{- "Type": "string",
- "MAC": "string",
- "Reason": "string",
- "Status": "string",
- "Router": "string"
}Endpoint for mesh nodes to notify the main router/AP about a station disconnection from the mesh network
| Event | string Type of event (e.g., "connect" or "disconnect") |
| Iface | string Network interface on the mesh node where the event occurred |
| Mac | string MAC address of the station |
| Router | string IP address of the mesh node reporting the event |
{- "Event": "string",
- "Iface": "string",
- "Mac": "string",
- "Router": "string"
}Mesh nodes handle this request when the main AP/Router sends down the devices listing
additional property | object (DeviceEntry) | ||||||||||||||||||
| |||||||||||||||||||
{- "property1": {
- "Name": "rpi4",
- "MAC": "11:22:33:44:55:61",
- "WGPubKey": "pubkey",
- "VLANTag": "vlantag",
- "RecentIP": "192.168.2.102",
- "PSKEntry": {
- "Type": "sae",
- "Psk": "password"
}, - "Policies": [
- "wan",
- "dns",
- "lan_upstream"
], - "Groups": [
- "cameras",
- "tvs"
], - "DeviceTags": [
- "private"
]
}, - "property2": {
- "Name": "rpi4",
- "MAC": "11:22:33:44:55:61",
- "WGPubKey": "pubkey",
- "VLANTag": "vlantag",
- "RecentIP": "192.168.2.102",
- "PSKEntry": {
- "Type": "sae",
- "Psk": "password"
}, - "Policies": [
- "wan",
- "dns",
- "lan_upstream"
], - "Groups": [
- "cameras",
- "tvs"
], - "DeviceTags": [
- "private"
]
}
}The main router uses this call to sync the OTP login code on the mesh nodes
| Token | string Authentication token for the request |
object (OTPSettings) |
{- "Token": "string",
- "Settings": {
- "OTPUsers": [
- {
- "Name": "string",
- "Secret": "string",
- "Confirmed": true,
- "AlwaysOn": true
}
], - "JWTDurationSeconds": 0
}
}Sets the credentials for the parent node in the mesh network, used for informing the parent about connection events
| ParentIP | string |
| ParentAPIToken | string |
| ParentCA | string |
{- "ParentIP": "string",
- "ParentAPIToken": "string",
- "ParentCA": "string"
}Retrieves the TLS certificate for the mesh network. This endpoint implements HMAC Authentication using the mesh node's API key.
| X-SPR-Mesh-TLS-Hash | string HMAC signature of the certificate file contents, using the Mesh's API Key. This header is used to verify the integrity and authenticity of the certificate. The client should validate this HMAC to ensure the certificate hasn't been tampered with. |
curl -u "admin:pass" \ "http://192.168.2.1/plugins/mesh/cert
PSKAuthFailure object that needs to be added
| Type | string |
| MAC | string/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/ |
| Reason | string |
| Status | string |
{- "Type": "sae",
- "MAC": "11:22:33:44:55:66",
- "Reason": "mismatch",
- "Status": "Okay"
}PSKAuthSuccess object that needs to be added
| Iface | string |
| Event | string |
| MAC | string/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/ |
| Status | string |
{- "Iface": "wlan1",
- "Event": "AP-STA-CONNECTED",
- "MAC": "11:22:33:44:55:66",
- "Status": "Okay"
}Handle networking tasks upon a DHCP
DHCPUpdate object that needs to be added
| IP | string/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/ |
| MAC | string/^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/ |
| Name | string |
| Iface | string |
| Router | string/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/ |
{- "IP": "192.168.2.102",
- "MAC": "11:22:33:44:55:66",
- "Name": "rpi4",
- "Iface": "wlan1",
- "Router": "192.168.2.1"
}Handle networking tasks for a new wireguard peer
WireguardUpdate object that needs to be added
| IP | string/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/ |
| PublicKey | string Base64 public key |
| Iface | string |
| Name | string |
{- "IP": "192.168.2.102",
- "PublicKey": "7SdFRh8o76RjUn/y4c7cQgCcCXA85s47/gVAdem3bBI=",
- "Iface": "wg0",
- "Name": "wfh-laptop"
}Handle networking tasks for removing a wireguard peer
WireguardUpdate object that needs to be added
| IP | string/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/ |
| PublicKey | string Base64 public key |
| Iface | string |
| Name | string |
{- "IP": "192.168.2.102",
- "PublicKey": "7SdFRh8o76RjUn/y4c7cQgCcCXA85s47/gVAdem3bBI=",
- "Iface": "wg0",
- "Name": "wfh-laptop"
}Get latest tag from git repository specified by the plugin parameter
| plugin | string plugin to get version for |
curl --unix-socket \ state/plugins/superd/socket \ http://localhost/git_version
"v0.1.23"Get latest tag from docker specified by the container parameter
| container | string container to get version for |
curl --unix-socket \ state/plugins/superd/socket \ http://localhost/container_version
"0.1.23"Reserves an IP address for plugins like wireguard to assign to clients
AbstractDHCPRequest for requesting an IP by an Identifier
| Identifier | string |
{- "Identifier": "7SdFRh8o76RjUn/y4c7cQgCcCXA85s47/gVAdem3bBI="
}| Name | string Client Name |
| MAC | string HW address |
| WGPubKey | string PubKey |
| VLANTag | string VLANTag |
| RecentIP | string RecentIP |
object (PSKEntry) | |
| Policies | Array of strings Policies for Device |
| Groups | Array of strings Interconnected Groups of Devices |
| DeviceTags | Array of strings Tags for Device |
{- "Name": "mbp",
- "MAC": "11:22:33:44:55:66",
- "WGPubKey": "",
- "VLANTag": "",
- "RecentIP": "192.168.2.102",
- "PskEntry": {
- "Type": "sae",
- "Psk": "**"
}, - "Policies": [
- "wan",
- "lan",
- "dns",
- "lan_upstream"
], - "Groups": [
- "cameras",
- "lightbulbs"
], - "DeviceTags": [
- "private"
]
}| Name | string Unique Group Name |
| Disabled | boolean If Group is disabled |
| GroupTags | Array of strings Tags for Group |
{- "Name": "vpn",
- "Disabled": false,
- "GroupTags": [
- "private"
]
}| Type | string Enum: "sae" "wpa" sae for WPA3 or wpa for WPA2 |
| Psk | string Password |
{- "Type": "sae",
- "Psk": "password"
}| Name | string Plugin name |
| URI | string Plugin URI |
| UnixPath | string Plugin path for unix socket |
| Enabled | boolean Plugin state |
| Plus | boolean Indicates if this is a PLUS plugin |
| GitURL | string Git repository URL for the plugin |
| ComposeFilePath | string Relative path to docker compose file |
| HasUI | boolean Indicates if the plugin has a user interface |
| SandboxedUI | boolean Indicates if the plugin UI is sandboxed |
| InstallTokenPath | string Path to the installation token |
| ScopedPaths | Array of strings List of scoped paths for the plugin |
{- "Name": "dns-block",
- "URI": "dns/block",
- "UnixPath": "/state/dns/dns_block_plugin",
- "Enabled": true
}