Service
capability to be enabled; see Management API for how
capabilities work. For what a service package is and how the Kernel
scans ServiceDir, see Services.
Discover and inspect services
List discovered services
ServiceDir before returning the result, so the list
always reflects the current contents of that directory. The response is a
services list, keyed by service name, where each entry combines package
metadata with the effective configuration and current lifecycle status.
By default, each entry omits two fields that can be large: package
metadata and configuration params. Add either or both with an
include query parameter, given as a comma-separated list, repeated, or
both:
metadata and params are the only supported values; anything else fails
with 400 Bad Request.
config shows the effective configuration merged from
[Services.default] and [Services.<name>]. config.params is withheld
even when include=metadata is present — it’s only returned when
include=params is added, unlike the rest of config, because params
can be arbitrarily large or hold values such as secrets pulled in through
env:// references.
List running services
ServiceDir — it
returns the Kernel’s live registry directly, so it only shows what is
actually running even if the directory currently holds packages that were
never started. There is no include parameter: a running entry always
shows its full detail, including the routes and transports it registered.
Entries are keyed by instance_id, the same projection described in
Routes and transports.
Get one discovered service
ServiceDir the same way GET /api/service/discovered does and
returns the single entry named {name}, or 404 Not Found if no
discovered service has that name. It accepts the same include query
parameter as the discovered list.
Start, stop, or restart a service
startstarts a previously scanned service by name.stopunloads a running service and removes its live host bindings, including every transport and route it registered.restartstops the running instance, then loads the latest scanned package for that service name.
GET /api/service/discovered (or
GET /api/service/detail/{name}) first if you’re not sure a package has
been picked up yet. A static service has no process to start or stop in
the operating-system sense, but it still goes through the same lifecycle:
starting it registers its declared transports and routes, and stopping it
removes them.
Service directory location
Read or change the scanned directory
GET returns the current service_dir. PATCH creates the directory if
it doesn’t exist, persists the new path, and immediately rescans it —
there’s no separate scan endpoint, and GET /api/service/discovered
always scans on every call anyway. The response reports how many packages
that scan found:
service_dir never requires a restart: every discovery call
reads it fresh, and this request already triggered a rescan against the
new path.
Read or change the temp directory
ServiceTempDir is where the Kernel extracts packages while loading
them. Unlike service_dir, it’s only read once, when the service manager
starts, so changing it here updates the value a future Kernel start will
use, but a currently running Kernel keeps extracting packages into the old
directory until it’s restarted. Both GET and PATCH report this with a
requires_restart boolean:
requires_restart is true whenever the configured temp_dir differs
from the one the running process actually applied at startup — including
on a plain GET, not just right after a PATCH. Sending the same value
again, or restarting the Kernel, brings it back to false.
Per-service configuration
Read, update, or reset a service’s config
[Services.<name>] table described in
Service configuration — Restart, RunAsUser,
Checksum, and Allow — independently of whether {name} currently
matches a discovered or running service. GET reports whether the name
has an explicit entry at all:
{name} has no entry in Services, the response is just
{"name": "login", "configured": false, "allow": null} — the service
still runs with [Services.default], this simply confirms there’s no
override.
PATCH takes a partial object; every field is optional, but at least one
must be present:
null or an empty string (clear the override and
fall back to [Services.default] for that field), or a value (set it).
allow follows the same present/null/value rule, except an explicit empty
list ("allow":[]) is a value, not a clear — it sets the service’s Allow
to an empty list, which is a public policy at that layer, rather than
removing the override. DELETE removes the entire [Services.<name>]
entry, including its Params, resetting the service fully to the default
configuration.
Per-service parameters
[Services.<name>.Params], the arbitrary key/value strings passed
to a service at registration. GET returns the current map, which is
null if nothing has been set. PATCH applies set and remove
together as one update; at least one of them must be non-empty. Both
calls work independently of {name} matching a discovered service, the
same as the config endpoints above.