Base URL: http://<host>:9090
All /api/* endpoints (except health and auth) require authentication via the mnm_token cookie.
Authenticate with the admin password.
Request:
{"password": "your-admin-password"}Response: 200 OK with Set-Cookie: mnm_token=...
{"status": "ok"}Check if the current session is authenticated.
Response:
{"authenticated": true}Clear the session cookie.
No authentication required.
Response:
{"status": "ok"}Returns health status of all MNM containers on the mnm-network.
Response:
{
"containers": [
{
"name": "mnm-nautobot",
"status": "running",
"health": "healthy",
"image": "mnm-nautobot:latest",
"ports": ["8443->8080/tcp"]
}
]
}Start a network sweep.
Request:
{
"cidr_ranges": ["192.0.2.0/24"],
"location_id": "uuid",
"secrets_group_id": "uuid",
"snmp_community": "public"
}Response: 200 OK
{"status": "started"}Poll sweep progress. Returns per-host enriched data.
Response:
{
"running": true,
"hosts": {
"192.0.2.1": {
"ip": "192.0.2.1",
"status": "known",
"ports_open": [22, 161, 830],
"mac_address": "aa:bb:cc:dd:ee:ff",
"mac_vendor": "Juniper Networks",
"dns_name": "firewall-01.example.com",
"snmp": {"sysName": "firewall-01", "sysDescr": "..."},
"classification": "network_device",
"first_seen": "2026-04-05T14:30:00Z",
"last_seen": "2026-04-06T02:00:00Z"
}
},
"summary": null
}Returns LLDP neighbors not matching known devices.
Response:
{
"neighbors": [
{
"neighbor_name": "ap-lobby-01",
"connected_to": "ge-0/0/5 (core-switch-01)"
}
]
}Onboard a single device (from LLDP advisory).
Request:
{
"ip": "192.0.2.50",
"location_id": "uuid",
"secrets_group_id": "uuid"
}Returns configured sweep schedules.
Save a sweep schedule.
Request:
{
"cidr_ranges": ["192.0.2.0/24"],
"location_id": "uuid",
"secrets_group_id": "uuid",
"interval_hours": 24
}Returns all collected endpoint records. Supports query parameters: ?vlan=100, ?switch=core-switch-01, ?mac_vendor=Apple, ?source=infrastructure
Returns summary stats: total endpoints, VLANs active, vendors seen, last collection time.
Response:
{
"total_endpoints": 147,
"vlans_active": 12,
"vendors_seen": 45,
"switches": 2,
"last_collection": "2026-04-06T14:00:00Z",
"running": false
}Manually trigger an endpoint collection run.
Returns all devices from Nautobot.
Returns a single device.
Returns available credential sets.
Returns available locations.
Returns controller configuration.
Update controller configuration (merge).
# Login
curl -c cookies.txt -X POST http://localhost:9090/api/auth/login \
-H "Content-Type: application/json" \
-d '{"password":"test123"}'
# Check status
curl -b cookies.txt http://localhost:9090/api/status
# Start sweep
curl -b cookies.txt -X POST http://localhost:9090/api/discover/sweep \
-H "Content-Type: application/json" \
-d '{"cidr_ranges":["192.0.2.0/29"],"location_id":"uuid","secrets_group_id":"uuid","snmp_community":"public"}'
# Poll progress
curl -b cookies.txt http://localhost:9090/api/discover/statusConsolidated view of all background tasks: sweep scheduler, modular poller, Proxmox collector, database prune, and legacy endpoint collector.
Response:
{
"jobs": [
{
"id": "sweep",
"name": "Sweep Scheduler",
"status": "idle",
"running": false,
"schedule_interval": "1h",
"last_run": "2026-04-09T22:10:00Z",
"duration_seconds": 285.3,
"summary": {"total": 254, "alive": 10, "known": 3},
"enabled": true
}
]
}Re-run the first saved sweep schedule. Used by the Jobs page "Run Now" button.
Response: 200 OK
{"status": "started", "cidr_ranges": ["198.51.100.0/24"]}Per-device, per-job-type collection tracking. Replaces the monolithic endpoint collector.
All devices, all job types, grouped by device.
Response:
{
"devices": [
{
"device_name": "core-switch-01",
"jobs": {
"arp": {"last_success": "2026-04-09T22:05:00Z", "interval_sec": 300, "enabled": true},
"mac": {"last_success": "2026-04-09T22:05:06Z", "interval_sec": 300, "enabled": true},
"dhcp": {"last_success": null, "interval_sec": 600, "enabled": true},
"lldp": {"last_success": "2026-04-09T21:30:00Z", "interval_sec": 3600, "enabled": true}
}
}
]
}Single device, all job types.
Trigger immediate poll of all enabled job types for a device. Returns 202 Accepted.
Trigger a single job type (arp, mac, dhcp, or lldp). Returns 202 Accepted.
Update interval or enabled flag for a specific device/job type.
Request:
{"interval_sec": 600, "enabled": false}Response: Updated poll row.
All tracked onboarding job states.
Detailed onboarding progress for a single host. Stages: submitting, queued, running, succeeded, failed, timeout.
Response:
{
"ip": "198.51.100.7",
"stage": "succeeded",
"message": "Device onboarded (core-switch-02)",
"job_result_id": "uuid",
"device_id": "uuid"
}These endpoints expose the MAC-keyed endpoint store backed by the
mnm_controller PostgreSQL database. They return empty results if the database
is unreachable; the controller will fall back to JSON for /api/config only.
Return the current identity record for one MAC.
Return all endpoint_events rows for a MAC, newest first.
Response: {"mac": "...", "events": [{"event_type": "moved_port", "old_value": "ge-0/0/12", "new_value": "ge-0/0/24", "timestamp": "..."}, ...]}
Return a chronological narrative for a MAC. Each entry has a human-readable
text describing the event, plus the underlying event_type and timestamp.
Response also includes the current endpoint record.
Recent network activity feed. Query params:
type(optional) —appeared,moved_port,moved_switch,ip_changed,hostname_changedsince(default24h) — duration string:1h,24h,7d,30dlimit(default200)
Return IPs currently claimed by more than one MAC. Each entry includes the list of conflicting endpoints with their switch/port context.
# Last day of port moves
curl -b cookies.txt 'http://localhost:9090/api/endpoints/events?type=moved_port&since=24h'
# Full timeline for one endpoint
curl -b cookies.txt http://localhost:9090/api/endpoints/AA:BB:CC:DD:EE:FF/timeline