📋 Interactive API Documentation (Swagger UI) 📄 Download OpenAPI Spec

🚀 Getting Started

Every endpoint answers JSON over plain GET requests; no key is needed except for the modem test writes. The OpenAPI document linked above is the authoritative contract: it lists every parameter and every response field, and the server's test suite checks it against the code. This page is the short tour.

Base URL: https://nodelist.fidonet.cc/api/

📐 Conventions

Networks. The database holds several FTN networks (FidoNet, fsxNet, ...) and a node address is only unique within one. GET /api/networks lists them. Most endpoints take ?domain=: endpoints about one address resolve it as explicit ?domain=, then the only network the address exists in, then fidonet; listings default to fidonet or to all networks as each description says. Responses about one address carry domain and available_domains (or the X-Available-Domains header when the body is the record itself).

Searches need a constraint. /api/nodes and /api/points answer 400 when no filter is given.

Limits. Every limit has a ceiling (500 on node and point searches, 200 on sysops, 1000 on reachability searches); the searches cap silently, the reachability endpoints reject values outside their range.

Errors are JSON {"error": "...", "status": 400, "time": "..."}. Requests are rate limited per client IP: an over-budget client gets 429 with a Retry-After header, and a query that outruns its time budget gets 503.

🔍 Nodes

GET /api/nodes — search nodelist entries. Filters: domain, zone, net, node, system_name, location, sysop_name (substrings, 2+ characters), node_type, is_cm, is_mo, has_inet, has_binkp, date_from, date_to, latest_only (one entry per node — its last one, not "still listed"), limit (default 100, max 500), offset.
GET /api/nodes/{zone}/{net}/{node} — the most recent entry of one address.
GET /api/nodes/{zone}/{net}/{node}/history — every entry, oldest first, with first and last dates.
GET /api/nodes/{zone}/{net}/{node}/changes — what changed on each nodelist date.
GET /api/nodes/{zone}/{net}/{node}/timeline — active/removed events for a chart.
GET /api/sysops, GET /api/sysops/{name}/nodes — operators and their nodes.
Examples:
GET /api/nodes?zone=2&is_cm=true&latest_only=true&limit=10
GET /api/nodes?location=Berlin&date_from=2020-01-01
GET /api/nodes/21/1/100?domain=fsxnet
GET /api/nodes/2/5001/100/history

📍 Points and Pointlists

GET /api/nodes/{zone}/{net}/{node}/points — the pointlist snapshot under a boss (?date= for an as-of date).
GET /api/points — search point entries (same filters as nodes plus point and list_source; latest_only=true gives snapshot semantics).
GET /api/points/{zone}/{net}/{node}/{point} and .../history — one point, now and over time.
GET /api/pointlists/sources, GET /api/pointlists/dates?source=z2 — the imported series and issues.

📊 Statistics

GET /api/networks — the FTN networks in the database with their latest nodelist date.
GET /api/stats?date=YYYY-MM-DD — node counts by type and capability, zone distribution, largest regions and nets, for one nodelist date (nearest available; the response says which). The statistics sit under stats next to domain, requested_date, actual_date and date_adjusted.
GET /api/stats/dates — every nodelist date for a network.
GET /api/flags?category=internet — flag documentation.
GET /api/nodelist/latest — the newest nodelist file and its download URL.

📡 Reachability and Testing

What the testing daemon found when it called each node over BinkP, IFCICO (EMSI), Telnet, FTP and VModem, over IPv4 and IPv6 — the data behind the Reachability pages.

GET /api/nodes/{zone}/{net}/{node}/tests?days=30 — one node's test results in the window, newest first, with success rates per protocol and address family under stats.
GET /api/nodes/{zone}/{net}/{node}/tests/detail?time=2026-09-10T12:00:00Z — one result in full, by its test_time.
GET /api/reachability/nodes?status=failed&protocol=binkp&days=1&limit=50 — each node's newest result, filtered by outcome and by which protocol succeeded.
GET /api/reachability/trends?days=90 — tested and operational node counts per day (omit days for the whole history).
GET /api/nodes/{zone}/{net}/{node}/ping, GET /api/analytics/pingtrace — netmail PING/TRACE (FTS-4010) measurements: the paths mail walked and who answered.
GET /api/software/binkp, /ifcico, /binkd — mailer software, versions and operating systems seen in handshakes.
GET /api/analytics/geo-hosting — where nodes are hosted, by country and provider.
Analytics endpoints take ?days= (default 365) and ?domain= (default: all networks).

☎️ PSTN and Modem Testing

GET /api/nodes/pstn — every node with a dialable phone number in the latest nodelist.
GET /api/nodes/pstn/dead, GET /api/nodes/pstn/recent-success?days=7 — numbers marked dead, and numbers a modem test reached recently.
POST /api/modem/results/direct, POST/DELETE /api/modem/pstn-dead — writes for the modem test caller; bearer API key required (see the README for issuing one).

📥 Nodelist and Pointlist File Downloads

The archive itself, per network. Files are stored gzipped and are decompressed on the way out; every download endpoint supports HTTP range requests. The same tree is served over FTP as /nodelists and /pointlists.

GET /download/nodelist/{network}/{year}/{filename} — one nodelist, e.g. /download/nodelist/fidonet/2024/nodelist.365
GET /download/latest — redirects to the newest FidoNet nodelist
GET /download/year/{network}/{year}.tar.gz — a year of one network, e.g. /download/year/fidonet/2024.tar.gz (served as fidonet-nodelists-2024.tar.gz)
GET /download/pointlist/{network}/{source}/{year}/{filename} — one pointlist issue, e.g. /download/pointlist/fidonet/z2/2025/z2pnt.206
GET /download/urls.txt — every nodelist URL, for mirroring: wget -nc -i https://nodelist.fidonet.cc/download/urls.txt

The pre-2026 FidoNet spellings without the network segment (/download/nodelist/2024/nodelist.365, /download/year/2024.tar.gz) still resolve but are no longer advertised.

💡 Usage Examples

# The networks in the database
curl "https://nodelist.fidonet.cc/api/networks"

# CM nodes in zone 2, one entry per node
curl "https://nodelist.fidonet.cc/api/nodes?zone=2&is_cm=true&latest_only=true&limit=5"

# One node, its history, and what the daemon found when it called
curl "https://nodelist.fidonet.cc/api/nodes/2/5001/100"
curl "https://nodelist.fidonet.cc/api/nodes/2/5001/100/history"
curl "https://nodelist.fidonet.cc/api/nodes/2/5001/100/tests?days=7"

# Nodes whose newest test failed today
curl "https://nodelist.fidonet.cc/api/reachability/nodes?status=failed&days=1"

# Statistics for the nearest nodelist to a date
curl "https://nodelist.fidonet.cc/api/stats?date=2023-12-01"

Response Shapes

Listings return the items under a named key with a count, and searches echo the filter they applied. Endpoints about one address add the address envelope:

{
  "address": "2:5001/100",
  "domain": "fidonet",
  "available_domains": ["fidonet"],
  "history": [...],
  "count": 52
}

Duplicate entries in the source nodelists are preserved: a node listed twice on one date has rows with conflict_sequence 0 and 1 and has_conflict set. Every field of every record is described in the OpenAPI document.