L2TP#
Live L2TP tunnels — downstream (from LACs, terminated on this LNS) and upstream (to wholesale LNSes).
2 operations. Roles, error format and pagination are common to the whole API — see the REST API overview.
Authentication
Use a named bearer token. Every endpoint except POST /api/v1/auth/login,
POST /api/v1/auth/enrol and GET /api/v1/system/health requires one. A super-user creates a
token with POST /api/v1/auth/tokens; the plaintext (bngtok_…) is returned exactly once at
creation and only a SHA-256 hash is stored on the appliance, so a lost token is replaced rather
than recovered. Send it on every request:
Each token carries a fixed role (read-only, operator or super-user) and is exempt from CSRF
checks. This is the single credential you need for scripts, integrations and monitoring.
Accounts and tokens share one identity model with the appliance CLI (login.users). Repeated
authentication failures lock the account/source-IP pair out temporarily (HTTP 423 on login).
Session cookies (bundled web UI only)
The appliance also accepts an interactive session cookie, which is how the bundled web UI authenticates. It is documented for completeness — API clients should not use it. It is bound to a login session and obliges the caller to manage a CSRF token, neither of which suits automation.
POST /api/v1/auth/login with username + password (and a TOTP code when enrolled) sets the
bng_session cookie and returns a csrfToken (also available from GET /api/v1/auth/whoami).
Cookie-authenticated mutating requests (anything other than GET/HEAD/OPTIONS) must also send
that value in the X-CSRF-Token header or they are rejected with 403.
NetavoBNG Management API v1#
L2TP#
GET /api/v1/l2tp/tunnels#
List live L2TP tunnels (both directions).
Description
"downstream" tunnels arrive from LACs and terminate on this appliance (LNS role); "upstream" tunnels carry wholesale PPPoE subscribers to a remote LNS (LAC role). Rows are ordered downstream-first, then by local tunnel id. Fleet-proxyable.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
bearerToken |
header | string | N/A | No | Named API token — the recommended credential for automation. See Authentication in the API overview. |
Responses
{
"tunnels": [
{
"direction": "downstream",
"localTunnelId": 5,
"peerTunnelId": 41027,
"peerIp": "203.0.113.10",
"peerHostname": "lac1.wholesale.example.net",
"peerVendor": "Cisco Systems, Inc.",
"state": "established",
"sessions": 303
}
]
}
Schema of the response body
{
"required": [
"tunnels"
],
"type": "object",
"properties": {
"tunnels": {
"type": "array",
"items": {
"$ref": "#/components/schemas/L2tpTunnel"
},
"description": "Live tunnels, downstream first, then by local tunnel id."
}
},
"description": "GET /api/v1/l2tp/tunnels response.",
"example": {
"tunnels": [
{
"direction": "downstream",
"localTunnelId": 5,
"peerTunnelId": 41027,
"peerIp": "203.0.113.10",
"peerHostname": "lac1.wholesale.example.net",
"peerVendor": "Cisco Systems, Inc.",
"state": "established",
"sessions": 303
}
]
}
}
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
"title": "VRF not found",
"status": 404,
"detail": "No VRF named 'wholesale-b' is configured.",
"instance": "/api/v1/vrfs/wholesale-b"
}
Schema of the response body
{
"type": "object",
"properties": {
"type": {
"type": "string",
"nullable": true
},
"title": {
"type": "string",
"nullable": true
},
"status": {
"pattern": "^-?(?:0|[1-9]\\d*)$",
"format": "int32",
"nullable": true
},
"detail": {
"type": "string",
"nullable": true
},
"instance": {
"type": "string",
"nullable": true
}
},
"example": {
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
"title": "VRF not found",
"status": 404,
"detail": "No VRF named 'wholesale-b' is configured.",
"instance": "/api/v1/vrfs/wholesale-b"
}
}
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
"title": "VRF not found",
"status": 404,
"detail": "No VRF named 'wholesale-b' is configured.",
"instance": "/api/v1/vrfs/wholesale-b"
}
Schema of the response body
{
"type": "object",
"properties": {
"type": {
"type": "string",
"nullable": true
},
"title": {
"type": "string",
"nullable": true
},
"status": {
"pattern": "^-?(?:0|[1-9]\\d*)$",
"format": "int32",
"nullable": true
},
"detail": {
"type": "string",
"nullable": true
},
"instance": {
"type": "string",
"nullable": true
}
},
"example": {
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
"title": "VRF not found",
"status": 404,
"detail": "No VRF named 'wholesale-b' is configured.",
"instance": "/api/v1/vrfs/wholesale-b"
}
}
GET /api/v1/l2tp/tunnels/{id}#
Full detail for one L2TP tunnel.
Description
Everything known about the tunnel — peer identity and vendor, endpoints, VRF, state, timestamps — plus the subscriber sessions carried in it. Fleet-proxyable.
Input parameters
| Parameter | In | Type | Default | Nullable | Description |
|---|---|---|---|---|---|
bearerToken |
header | string | N/A | No | Named API token — the recommended credential for automation. See Authentication in the API overview. |
id |
path | integer | No | The tunnel's local tunnel id (from the tunnel list). |
Responses
{
"found": true,
"direction": "downstream",
"localTunnelId": 5,
"peerTunnelId": 41027,
"peerIp": "203.0.113.10",
"peerPort": 1701,
"peerHostname": "lac1.wholesale.example.net",
"peerVendor": "Cisco Systems, Inc.",
"localEndpoint": "45.84.200.69",
"vrfName": "transit",
"state": "established",
"sessions": 2,
"createdUtc": "2026-08-02T09:11:04Z",
"uptimeSeconds": 90546.214773,
"lastActivityUtc": "2026-08-03T10:23:59Z",
"sessionList": [
{
"id": 40213,
"username": "alice@example.net",
"encap": "l2tp",
"ipv4": "100.64.12.37",
"ipv6": "2001:db8:64:12::1",
"localSessionId": 118,
"peerSessionId": 9,
"uptimeSeconds": 86412.538912
}
]
}
Schema of the response body
{
"type": "object",
"properties": {
"found": {
"type": "boolean",
"description": "Always true on a 200 (unknown tunnels return 404)."
},
"direction": {
"type": "string",
"description": "\"downstream\" (from a LAC, terminated here) or \"upstream\" (to a wholesale LNS)."
},
"localTunnelId": {
"pattern": "^-?(?:0|[1-9]\\d*)$",
"description": "Tunnel id on this appliance.",
"format": "int32"
},
"peerTunnelId": {
"pattern": "^-?(?:0|[1-9]\\d*)$",
"description": "Tunnel id on the peer.",
"format": "int32"
},
"peerIp": {
"type": "string",
"description": "Peer tunnel endpoint IP, or null when unknown.",
"nullable": true
},
"peerPort": {
"pattern": "^-?(?:0|[1-9]\\d*)$",
"description": "Peer UDP port, or null when unknown.",
"format": "int32",
"nullable": true
},
"peerHostname": {
"type": "string",
"description": "The peer's L2TP Host Name AVP, or null when unknown.",
"nullable": true
},
"peerVendor": {
"type": "string",
"description": "The peer's Vendor Name AVP, or null when unknown.",
"nullable": true
},
"localEndpoint": {
"type": "string",
"description": "Local tunnel endpoint IP on this appliance, or null when unknown.",
"nullable": true
},
"vrfName": {
"type": "string",
"description": "Transport VRF the tunnel rides in, or null for the global table.",
"nullable": true
},
"state": {
"type": "string",
"description": "Tunnel state: idle | wait-ctl | established | closed."
},
"sessions": {
"pattern": "^-?(?:0|[1-9]\\d*)$",
"description": "Subscriber sessions currently carried in the tunnel.",
"format": "int32"
},
"createdUtc": {
"type": "string",
"description": "UTC time the tunnel was established.",
"format": "date-time",
"nullable": true
},
"uptimeSeconds": {
"pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?(?:[eE][+-]?\\d+)?$",
"description": "How long the tunnel has been up, in seconds (from DateTime? L2tpTunnelDetailDto.CreatedUtc to now),\n or null when the establishment time is unknown.",
"format": "double",
"nullable": true
},
"lastActivityUtc": {
"type": "string",
"description": "UTC time of the last session activity seen in the tunnel.",
"format": "date-time",
"nullable": true
},
"sessionList": {
"type": "array",
"items": {
"$ref": "#/components/schemas/L2tpTunnelSession"
},
"description": "The subscriber sessions carried in the tunnel."
}
},
"description": "GET /api/v1/l2tp/tunnels/{id} — full detail for one tunnel + its subscriber sessions.",
"example": {
"found": true,
"direction": "downstream",
"localTunnelId": 5,
"peerTunnelId": 41027,
"peerIp": "203.0.113.10",
"peerPort": 1701,
"peerHostname": "lac1.wholesale.example.net",
"peerVendor": "Cisco Systems, Inc.",
"localEndpoint": "45.84.200.69",
"vrfName": "transit",
"state": "established",
"sessions": 2,
"createdUtc": "2026-08-02T09:11:04Z",
"uptimeSeconds": 90546.214773,
"lastActivityUtc": "2026-08-03T10:23:59Z",
"sessionList": [
{
"id": 40213,
"username": "alice@example.net",
"encap": "l2tp",
"ipv4": "100.64.12.37",
"ipv6": "2001:db8:64:12::1",
"localSessionId": 118,
"peerSessionId": 9,
"uptimeSeconds": 86412.538912
}
]
}
}
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
"title": "VRF not found",
"status": 404,
"detail": "No VRF named 'wholesale-b' is configured.",
"instance": "/api/v1/vrfs/wholesale-b"
}
Schema of the response body
{
"type": "object",
"properties": {
"type": {
"type": "string",
"nullable": true
},
"title": {
"type": "string",
"nullable": true
},
"status": {
"pattern": "^-?(?:0|[1-9]\\d*)$",
"format": "int32",
"nullable": true
},
"detail": {
"type": "string",
"nullable": true
},
"instance": {
"type": "string",
"nullable": true
}
},
"example": {
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
"title": "VRF not found",
"status": 404,
"detail": "No VRF named 'wholesale-b' is configured.",
"instance": "/api/v1/vrfs/wholesale-b"
}
}
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
"title": "VRF not found",
"status": 404,
"detail": "No VRF named 'wholesale-b' is configured.",
"instance": "/api/v1/vrfs/wholesale-b"
}
Schema of the response body
{
"type": "object",
"properties": {
"type": {
"type": "string",
"nullable": true
},
"title": {
"type": "string",
"nullable": true
},
"status": {
"pattern": "^-?(?:0|[1-9]\\d*)$",
"format": "int32",
"nullable": true
},
"detail": {
"type": "string",
"nullable": true
},
"instance": {
"type": "string",
"nullable": true
}
},
"example": {
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
"title": "VRF not found",
"status": 404,
"detail": "No VRF named 'wholesale-b' is configured.",
"instance": "/api/v1/vrfs/wholesale-b"
}
}
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
"title": "VRF not found",
"status": 404,
"detail": "No VRF named 'wholesale-b' is configured.",
"instance": "/api/v1/vrfs/wholesale-b"
}
Schema of the response body
{
"type": "object",
"properties": {
"type": {
"type": "string",
"nullable": true
},
"title": {
"type": "string",
"nullable": true
},
"status": {
"pattern": "^-?(?:0|[1-9]\\d*)$",
"format": "int32",
"nullable": true
},
"detail": {
"type": "string",
"nullable": true
},
"instance": {
"type": "string",
"nullable": true
}
},
"example": {
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
"title": "VRF not found",
"status": 404,
"detail": "No VRF named 'wholesale-b' is configured.",
"instance": "/api/v1/vrfs/wholesale-b"
}
}
Schemas#
L2tpTunnel#
| Name | Type | Description |
|---|---|---|
direction |
string | "downstream" (from a LAC, terminated here) or "upstream" (to a wholesale LNS). |
localTunnelId |
Tunnel id on this appliance — the key for the detail endpoint. | |
peerHostname |
string | null | The peer's L2TP Host Name AVP, or null when unknown. |
peerIp |
string | null | Peer tunnel endpoint IP, or null when unknown. |
peerTunnelId |
Tunnel id on the peer. | |
peerVendor |
string | null | The peer's Vendor Name AVP (RFC 2661 §4.4.3) — the LAC/LNS software/vendor string. Only the live manager captures it; null on session-derived rows unless in demo mode. |
sessions |
Subscriber sessions currently carried in the tunnel. | |
state |
string | Tunnel state: idle | wait-ctl | established | closed. |
L2tpTunnelDetail#
| Name | Type | Description |
|---|---|---|
createdUtc |
string(date-time) | null | UTC time the tunnel was established. |
direction |
string | "downstream" (from a LAC, terminated here) or "upstream" (to a wholesale LNS). |
found |
boolean | Always true on a 200 (unknown tunnels return 404). |
lastActivityUtc |
string(date-time) | null | UTC time of the last session activity seen in the tunnel. |
localEndpoint |
string | null | Local tunnel endpoint IP on this appliance, or null when unknown. |
localTunnelId |
Tunnel id on this appliance. | |
peerHostname |
string | null | The peer's L2TP Host Name AVP, or null when unknown. |
peerIp |
string | null | Peer tunnel endpoint IP, or null when unknown. |
peerPort |
Peer UDP port, or null when unknown. | |
peerTunnelId |
Tunnel id on the peer. | |
peerVendor |
string | null | The peer's Vendor Name AVP, or null when unknown. |
sessionList |
Array<L2tpTunnelSession> | The subscriber sessions carried in the tunnel. |
sessions |
Subscriber sessions currently carried in the tunnel. | |
state |
string | Tunnel state: idle | wait-ctl | established | closed. |
uptimeSeconds |
How long the tunnel has been up, in seconds (from DateTime? L2tpTunnelDetailDto.CreatedUtc to now), or null when the establishment time is unknown. | |
vrfName |
string | null | Transport VRF the tunnel rides in, or null for the global table. |
L2tpTunnelList#
| Name | Type | Description |
|---|---|---|
tunnels |
Array<L2tpTunnel> | Live tunnels, downstream first, then by local tunnel id. |
L2tpTunnelSession#
| Name | Type | Description |
|---|---|---|
encap |
string | null | Access encapsulation ("l2tp" downstream, "pppoe-lac" upstream). |
id |
BNG session id (key into /api/v1/sessions/{id}). | |
ipv4 |
string | null | Assigned IPv4 address, or null. |
ipv6 |
string | null | IPv6 WAN address, or null. |
localSessionId |
L2TP session id on this appliance. | |
peerSessionId |
L2TP session id on the peer. | |
uptimeSeconds |
Seconds since the session was established. | |
username |
string | null | Subscriber username, or null when unknown. |
ProblemDetails#
| Name | Type | Description |
|---|---|---|
detail |
string | null | |
instance |
string | null | |
status |
||
title |
string | null | |
type |
string | null |
Security schemes#
| Name | Type | Scheme | Description |
|---|---|---|---|
| bearerToken | http | bearer | Named API token — the recommended credential for automation. See Authentication in the API overview. |
| sessionCookie | apiKey | Interactive session cookie used by the bundled web UI. Not the integration path for API clients — use a bearer token. See Authentication in the API overview. |
Tags#
| Name | Description |
|---|---|
| L2TP | Live L2TP tunnels — downstream (from LACs, terminated on this LNS) and upstream (to wholesale LNSes). |