API v1 (Beta)
Beta
The v1 API is in beta. Endpoints and behaviour may change without notice while it is under active development. Full endpoint documentation is coming later — for now this page covers the basics and how to extend it. The stable, fully documented API remains v0.
The v1 API is disabled by default. Enable it with lnms config:set api.v1.enabled true, or in the web UI under Settings → API → API v1 (Beta). When disabled, all /api/v1 endpoints return 404 and v1 token management is hidden from the web UI.
Overview
The v1 API is served under the /api/v1 prefix and is built on Laravel Restify with Sanctum bearer-token authentication.
Authentication
Most v1 endpoints require a personal access token sent as a bearer token:
curl -H 'Authorization: Bearer YOURAPITOKENHERE' https://librenms.org/api/v1/health
Create a v1 token from the web interface at /api-access/ under the API v1 tokens section.
Available endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /api/v1/ping | none (public) | Liveness probe. Returns {"status":"ok"}. |
GET | /api/v1/health | bearer token | Subsystem health (database, cache). |
More endpoints will be added as the v1 API matures.
Adding custom endpoints
There are two places to add v1 functionality, depending on whether you need a plain route or a full CRUD resource.
1. Custom (non-repository) endpoints
Routes that are not backed by a Restify repository — health checks, actions, reports, etc. — are registered in the routes() method of app/Providers/RestifyServiceProvider.php, under the api/v1 prefix. Point each route at an invokable controller in app/Http/Controllers/Api/V1/.
// app/Providers/RestifyServiceProvider.php
protected function routes(): void
{
Route::prefix('api/v1')->group(function (): void {
// Public, unauthenticated endpoint.
Route::get('ping', PingController::class)->name('v1.ping');
// Authenticated endpoint — add the sanctum middleware.
Route::get('health', HealthController::class)
->middleware('auth:sanctum')
->name('v1.health');
});
parent::routes();
// ...
}
A minimal controller:
// app/Http/Controllers/Api/V1/PingController.php
namespace App\Http\Controllers\Api\V1;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
class PingController extends Controller
{
public function __invoke(): JsonResponse
{
return response()->json(['status' => 'ok']);
}
}
Guidelines:
- Place controllers in
app/Http/Controllers/Api/V1/. - Add
->middleware('auth:sanctum')to any route that should require a token. Leave it off only for intentionally public endpoints (e.g.ping). - Register custom routes before
parent::routes()so they are defined alongside the Restify-managed routes.
2. Restify repository (CRUD) resources
For standard create/read/update/delete access to a model, add a Restify repository in app/Restify/ and register it in the boot() method of RestifyServiceProvider:
// app/Providers/RestifyServiceProvider.php
public function boot(): void
{
parent::boot();
Restify::repositories([
\App\Restify\DeviceRepository::class,
// ...add repositories here as v1 resources are introduced
]);
}
Restify then generates the standard resource routes (index, show, store, update, destroy) under /api/v1 automatically. See the Laravel Restify documentation for how to define repositories, fields, and authorization.
After changing routes
Route and config are cached on container start, so after adding or changing endpoints clear the caches:
php artisan route:clear
php artisan config:clear
Verify the result with php artisan route:list --path=api/v1.