Skip to content

System API

The endpoints on this page describe the router as a whole: its status, its health checks, its backups and saved configuration versions, and the traffic graphs it draws. For the base URL, authentication and error format, see the API overview.

A one-call summary of the router: version, whether the DHCP service is running, how many legacy per-MAC clients are registered and online, clients per network, and the anti-spoofing mode.

Terminal window
curl -s http://ROUTER-IP:8880/status -H "X-API-Key: YOUR_API_KEY"
{
"api": "DTVSOL DHCP API v1.0",
"router_version": "2026.09.27",
"dhcp_service": "running",
"total_clients": 42,
"online_clients": 37,
"per_network": {
"10.110.0.0/21": 42
},
"interfaces": 6,
"antispoof": "strict",
"server_time": "2026-09-28 10:15:00"
}

antispoof is the configured mode (strict or dynamic) when anti-spoofing is enabled, otherwise off. online_clients counts clients whose address is currently a live neighbour of the router.

The configuration doctor: a full audit of the router’s configuration and of what survives a reboot (addresses, VLANs, DHCP and router-advertisement configuration, data files, the configuration store, NTP for the OLTs). With ?olt=1 it also checks each registered OLT against the router’s records. It only reads.

Name In Type Notes
olt query boolean 1 also checks the registered OLTs (slower). Omitted: the router only.
Terminal window
curl -s "http://ROUTER-IP:8880/doctor?olt=1" -H "X-API-Key: YOUR_API_KEY"
{
"ok": true,
"code": 200,
"generated": "2026-09-28 10:15:00",
"count": 1,
"counts": {
"critical": 0,
"warning": 1,
"info": 0
},
"findings": [
{
"severity": "warning",
"area": "dhcp",
"problem": "…",
"detail": "…",
"fix": "…"
}
]
}

ok is true when there are no critical findings. Each finding carries a severity (critical, warning or info), the area it concerns, the problem, a detail and a suggested fix. The HTTP status is always 200; read ok and counts.

The CLI equivalent is dtvsol doctor (with the OLT checks) or dtvsol doctor --no-olt.

The conditions worth attention right now: the DHCP service down, VLAN links down, address pools nearly full, the CGNAT pool, anti-spoofing drops, unknown devices, OLT and fibre problems reported by the OLT collector, and the licence. It only reads.

Terminal window
curl -s http://ROUTER-IP:8880/alerts -H "X-API-Key: YOUR_API_KEY"
{
"count": 2,
"generated": "2026-09-28 10:15:00",
"alerts": [
{
"severity": "critical",
"type": "dhcp",
"message": "DHCP service is not running"
},
{
"severity": "warning",
"type": "olt",
"olt": "olt-1",
"message": "OLT olt-1: …"
}
]
}

severity is critical, warning or info. type is one of dhcp, interface, dhcp-pool, stranger, cgnat, spoof, olt, fiber or licence; OLT and fibre alerts also name the olt (and, for fibre, the port and ONT).

For alarms with a history (raised, cleared, acknowledged), see the Alarms and health API.

Downloads a full backup of the router as a .tar.gz archive: the etc/ and data/ directories, with the configuration database included as a consistent copy taken at that moment. The response is the archive itself (Content-Type: application/gzip, with a Content-Disposition file name such as dtvsol-router-backup-20260928-101500.tar.gz).

Terminal window
curl -s http://ROUTER-IP:8880/backup -H "X-API-Key: YOUR_API_KEY" -OJ

On failure the answer is JSON with status 500:

{
"error": "Backup failed",
"detail": "…"
}

The CLI equivalent is dtvsol backup [outfile.tar.gz].

Restores a backup archive that is already on the router (upload it first, for example with scp). Before unpacking, the current configuration is saved as a new configuration version, so the restore can itself be undone with dtvsol config restore <undo_version> --yes. After unpacking, the router rewrites the DHCP host files and reapplies shaping, accounting, CGNAT, port forwards, anti-spoofing and the firewall rules.

Name In Type Notes
file body string Path of the .tar.gz archive on the router. Required.
Terminal window
curl -s -X POST http://ROUTER-IP:8880/restore \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"file": "/root/dtvsol-router-backup-20260928-101500.tar.gz"}'
{
"ok": true,
"code": 200,
"message": "Restored and services reapplied",
"documents": ["clients", "services"],
"undo_version": 57
}

Errors: 400 when the file is missing ("Provide an existing backup file path (upload it to the router first)") or is not a valid tar.gz; 500 when extraction fails, or when the archive was unpacked but its configuration documents could not all be brought in — that answer includes undo_version and a next hint with the command that returns to the configuration before the restore.

The CLI equivalent is dtvsol restore <file.tar.gz>.

The router keeps saved versions of its configuration in its database, like a switch’s saved configuration in flash. Over HTTP these are reached only through the action API (/api?action=…); parameters go in the query string, or for POST in a JSON body (the body wins, the query string fills in what the body lacks). The CLI equivalent is dtvsol config ….

Action Method Parameters What it does
action=config-status GET — Which saved version the running configuration matches, the latest version id, and whether there are unsaved changes (files added, removed, changed).
action=config-versions GET n (default 30, 1–1000) The newest saved versions: id, saved_at, saved_by, comment, auto, files, bytes, digest.
action=config-save POST comment (optional, up to 200 characters) Changes the router: saves the running configuration as a new version. A GET is refused with 405. Answers 201.
action=config-diff GET from (version id, required), to (version id or running, default running) What changed between two versions, or between a version and the running configuration.
action=config-show GET id (version id, required), path (optional) Without path: the list of files in that version. With path: that file’s content, with passwords, keys and tokens masked.

Restoring a saved version is done from the CLI: dtvsol config restore <id> --yes.

Terminal window
curl -s "http://ROUTER-IP:8880/api?action=config-status" -H "X-API-Key: YOUR_API_KEY"
{
"ok": true,
"saved": {
"id": 57,
"saved_at": "2026-09-28 09:00:00",
"comment": "before maintenance"
},
"latest": 57,
"unsaved": true,
"changes": {
"added": [],
"removed": [],
"changed": ["data/services.json"]
},
"code": 200
}
Terminal window
curl -s -X POST "http://ROUTER-IP:8880/api?action=config-save" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"comment": "new plans for October"}'
{
"ok": true,
"saved": true,
"version": 58,
"files": 24,
"message": "…",
"code": 201
}
Terminal window
curl -s "http://ROUTER-IP:8880/api?action=config-diff&from=57&to=running" -H "X-API-Key: YOUR_API_KEY"
{
"ok": true,
"from": 57,
"to": "running",
"changes": {
"added": [],
"removed": [],
"changed": ["data/services.json"]
},
"diff": "…",
"code": 200
}
Terminal window
curl -s "http://ROUTER-IP:8880/api?action=config-show&id=57" -H "X-API-Key: YOUR_API_KEY"
{
"ok": true,
"version": 57,
"files": ["etc/config.php", "data/services.json"],
"code": 200
}

Errors: 400 for a missing or non-numeric from/id, or a to that is neither a version id nor running; 404 for a version (or a file in a version) that does not exist; 500 when the store cannot be read.

Graphs are returned as PNG images (Content-Type: image/png). When no graph can be drawn the answer is JSON: {"error": "…"} with status 400 (bad parameters), 404 (no data yet — samples are collected every minute) or 500 (drawing failed).

Traffic of one subscriber or one interface. {name} is a service id (svc_ followed by 8 hex digits), a client MAC address, or an interface name (for example vlan100).

Name In Type Notes
name path string Service id, MAC address or interface name.
period query string hour (last 3 hours), day (default), week, month or year.
Terminal window
curl -s "http://ROUTER-IP:8880/graph/vlan100?period=week" \
-H "X-API-Key: YOUR_API_KEY" -o graph.png

Traffic of an OLT PON port, an uplink port, or a whole card (all its ports), from the OLT collector’s samples.

Name In Type Notes
olt query string Registered OLT name. Required.
port query string F/S/P for a port, or F/S for a whole card. Required.
pon query boolean 1 (default): a PON port; 0: an uplink port.
period query string hour, day (default), week, month, quarter, year or 2years.
Terminal window
curl -s "http://ROUTER-IP:8880/graph/oltport?olt=olt-1&port=0/1/3&period=month" \
-H "X-API-Key: YOUR_API_KEY" -o graph.png

Traffic or error counters of one ONT, as seen by the OLT.

Name In Type Notes
olt query string Registered OLT name. Required.
port query string PON port F/S/P. Required.
ont query integer ONT id on that port. Required.
what query string traffic (default) or errors.
period query string hour, day (default), week, month, quarter, year or 2years.
Terminal window
curl -s "http://ROUTER-IP:8880/graph/ont?olt=olt-1&port=0/1/3&ont=12&what=errors" \
-H "X-API-Key: YOUR_API_KEY" -o graph.png

Traffic of one service. {id} is anything that identifies the service (see the Services API).

Name In Type Notes
id path string Service id or another key of the service.
source query string router (default): traffic through the router; olt: traffic of its ONT as the OLT counts it; errors: the ONT’s error counters.
period query string For router: hour, day (default), week, month, year. For olt/errors: also quarter and 2years.
Terminal window
curl -s "http://ROUTER-IP:8880/services/svc_1a2b3c4d/graph?source=olt&period=week" \
-H "X-API-Key: YOUR_API_KEY" -o graph.png

Errors: 404 "No such service", or "This service has no ONT" for source=olt|errors on a service without an ONT.

The router’s licence is not exposed over the HTTP API. It is managed on the router with the CLI:

Command What it does
dtvsol licence status Shows whether the router is enrolled, the licence provider, whether the licence is valid (and why not), its expiry date with the days left, the last refresh (time and result), and a note about the clock.
dtvsol licence refresh Fetches a fresh licence now (a timer also does this daily).
dtvsol licence enrol <id> <token|-> Enrols the router with the id and token issued for it; - reads the token from standard input.

An expiring or invalid licence also shows up as a licence alert in GET /alerts.

Action Same as
action=status GET /status
action=doctor (&olt=1) GET /doctor
action=alerts GET /alerts
action=config-status dtvsol config status
action=config-versions dtvsol config versions [n]
action=config-save (POST) dtvsol config save ["comment"]
action=config-diff dtvsol config diff <a> [b|running]
action=config-show dtvsol config show <id> [path]