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: