0.0.0.0:8080 (change with the PORT environment variable). It is the same API the local UI uses. It is unauthenticated and intended for your LAN — do not expose port 8080 to the internet. Remote access goes through cloud pairing instead.
Base URL in the examples: http://nvr.local:8080.
GET /api/status
Node identity, cloud link state, go2rtc health, and cameras.cloud.state is one of disabled, registering, unclaimed (with claimCode and claimCodeExpiresAt), connecting, online, or error (with message). nodeId is null before first registration. Camera objects never include RTSP URLs.
GET /api/events
The 50 most recent local events, newest first.kind is motion, person, vehicle, animal, or package. clipStatus is local, uploading, or uploaded.
GET /api/cameras
Cameras with their live/online state (same shape ascameras in /api/status).
POST /api/cameras
Add a camera.name and rtspUrl are required; rtspSubUrl, make, and model are optional. The node probes the stream on add (a failed probe still adds the camera, with empty capabilities). Returns 201 with the created camera, or 400 on an invalid body.
DELETE /api/cameras/{id}
Remove a camera. Returns204 on success, 404 if the id is unknown.
POST /api/cameras/{id}/probe
Re-probe the camera’s main stream with ffprobe (TCP transport, 10 s timeout) and store the result. Returns the capabilities,404 for an unknown camera, or 502 if the probe fails.
POST /api/whep/{cameraId}
WHEP endpoint for local live view. Send an SDP offer with content typeapplication/sdp; the node proxies it to go2rtc and returns the SDP answer with status 201. The browser UI uses this so it never talks to go2rtc (:1984) directly.
404 unknown camera, 400 missing/empty SDP body, 502 go2rtc unreachable or stream unavailable.