License
Get License Status
GET /api/v1/license
Returns the durable admission mode, deadlines, capacity and licensee information. Available to all authenticated users; no license mode blocks topology reads or WebSockets.
Response: 200 OK
{
"mode": "overage_grace",
"valid": true,
"evaluation": false,
"grace_period": true,
"days_left": 312,
"node_limit": 500,
"current_nodes": 517,
"over_by": 17,
"new_nodes_allowed": true,
"available_new_nodes": null,
"existing_nodes_live": true,
"restriction_reasons": ["node_overage"],
"overage_ends_at": "2026-09-30T12:00:00Z",
"license_id": "OSP-2027-0001",
"licensee": "Megacorp Inc. (USA)",
"tier": "enterprise",
"issued_at": "2026-03-07T10:00:00Z",
"expires_at": "2027-03-07T10:00:00Z"
}
Evaluation mode (no license installed). Evaluation has no overage grace, so
available_new_nodes is always present — it is the number of devices that may
still be admitted, and mode becomes restricted the moment the count exceeds
node_limit:
{
"mode": "active",
"valid": true,
"evaluation": true,
"grace_period": false,
"days_left": 0,
"node_limit": 32,
"current_nodes": 5,
"new_nodes_allowed": true,
"available_new_nodes": 27
}
Response fields:
| Field |
Type |
Description |
mode |
string |
active, overage_grace, expiry_grace, or restricted. The two grace modes require a signed license; an evaluation install over its cap goes straight to restricted |
valid |
boolean |
Whether the license is currently valid (includes grace period) |
evaluation |
boolean |
True only when no signed license is installed |
grace_period |
boolean |
Compatibility summary for either grace mode |
frozen |
boolean |
Deprecated 1.4.x compatibility field; always false |
days_left |
integer |
Days remaining until expiry (negative during grace period, 0 for evaluation) |
node_limit |
integer |
Maximum number of monitored devices (0 = unlimited) |
current_nodes |
integer |
Current deployment-wide non-collector device count; the status read is lock-free/read-only and returns 503 if durable state cannot be inspected safely |
over_by |
integer |
Nodes above the effective cap |
new_nodes_allowed |
boolean |
Whether at least one new identity can currently be admitted |
available_new_nodes |
integer/null |
Remaining admissible capacity. Non-null whenever a hard cap applies — always in evaluation mode (which has no grace) and after a licensed grace window ends. Null while unlimited, and null during a licensed overage or expiry grace, where admission is deliberately uncapped |
existing_nodes_live |
boolean |
Always true |
restriction_reasons |
array |
Applicable node_overage and/or license_expired reasons |
overage_started_at, overage_ends_at |
timestamp/null |
Durable node-overage episode. Always null in evaluation mode: no episode is recorded, so nothing can later re-arm a second grace window |
license_expires_at, expiry_grace_ends_at |
timestamp/null |
Signed expiry and 30-day expiry deadline |
clock_anomaly_at |
timestamp/null |
Last persisted continuous-process clock-step warning; does not freeze existing topology |
rejected_sources |
array |
Bounded/debounced admission-refusal summaries per discovery source and reason (batch_exceeds_capacity or identity_conflict) |
error |
string |
Error message if license validation failed (omitted when empty) |
license_id |
string |
License identifier (omitted in evaluation mode) |
licensee |
string |
Licensee name and country (omitted in evaluation mode) |
tier |
string |
License tier: enterprise, professional, etc. (omitted in evaluation mode) |
issued_at |
string |
ISO 8601 timestamp when the license was issued |
expires_at |
string |
ISO 8601 timestamp when the license expires |
Upload License (Admin)
POST /api/v1/license
Validates signature and payload without changing runtime state, then commits license.key and the reconciled singleton atomically under the same advisory lock as node admission. Runtime status, file copy and NATS events change only after commit. Admin-only.
Request body:
{
"license_key": "eyJsaWNlbnNlX2lkIjoiT1NQLTIwMjctMDAwMSIs..."
}
Response: 200 OK — Same schema as GET /api/v1/license.
A committed upload publishes a rediscovery edge whenever it removes a
restriction or increases finite replacement capacity. An expired signed
entitlement with max_nodes=0 remains visibly expired but has no finite cap,
so its mode is active and new discovery remains unrestricted.
Error responses:
400 Bad Request — Invalid license format, tampered signature, or missing license_key field
401 Unauthorized — Missing or invalid access token
403 Forbidden — Non-admin user
503 Service Unavailable — Enforcer unavailable or the primary DB commit failed; the previous active license remains unchanged