Skip to content

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.