> ## Documentation Index
> Fetch the complete documentation index at: https://docs.arupa.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Services

> Install and manage Arupa services through the service directory and API.

The Kernel discovers services from `ServiceDir`. A service package is a `.plg`
file. The Kernel scans that directory, reads each package's `info.yaml`, and
uses the service configuration to decide whether to start it.

## Install a service

Arupa does not upload service packages through the management API. To install
a service:

1. Place its `.plg` package in the configured `ServiceDir`.
2. Make sure the Kernel can write to `ServiceTempDir`, which it uses while
   loading service packages.
3. Scan the directory through the API, or restart Arupa so it scans the
   directory during startup.
4. Start the service if its effective `Restart` setting does not enable
   automatic startup.

The default directories are:

```toml theme={null}
ServiceDir = "services"
ServiceTempDir = "tmp"
```

The package must be a valid service archive with a root-level `info.yaml`.
That metadata must provide the service name, version, runtime type (`wasm`,
`grpc`, or `static`), contract version, and, for `wasm` and `grpc` services, a
command to start. Files that are not `.plg` packages are ignored during a
scan.

See [Service configuration](./config-services) for
automatic startup, execution users, access groups, and service parameters.

## Management API

All service management endpoints are under `/api/services` and require an
authenticated user. They return the standard JSON response shape used by
Arupa: `success`, `message`, and `data`.

### List service state

```http theme={null}
GET /api/services
```

This endpoint scans the configured `ServiceDir` before returning the result,
so the list always reflects the current contents of that directory; there is
no separate scan endpoint. The response includes the configured
`service_dir` and `service_temp_dir`, a `discovered` list, and a `running`
list. Discovered entries include package metadata, effective configuration,
and lifecycle status. Running entries include the routes and transports
registered by each running service.

### Start, stop, or restart a service

Use the same request body for all three actions:

```http theme={null}
POST /api/services/start
POST /api/services/stop
POST /api/services/restart
Content-Type: application/json

{"name":"hello"}
```

* `start` starts a previously scanned service by name.
* `stop` unloads a running service and removes its live host bindings,
  including every transport and route it registered.
* `restart` stops the running instance, then loads the latest scanned package
  for that service name.

The `name` field is required. These actions do not accept a package path; the
service must already be present in the scan results.

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.

### Read service directory configuration

```http theme={null}
GET /api/services/config
```

The response returns the current `service_dir` and `service_temp_dir`.

### Update service directory configuration

```http theme={null}
PUT /api/services/config
Content-Type: application/json

{
  "service_dir": "services",
  "service_temp_dir": "tmp"
}
```

Both fields are required. The API creates the directories before saving the
configuration, updates the manager, and scans the new service directory.

Changing `service_dir` takes effect for scanning immediately. Changing
`service_temp_dir` is reported with `temp_dir_requires_restart: true` because
the service manager initializes its extraction directory when it starts.

## Authentication and access

Every endpoint in this page uses the Kernel's authentication middleware. An
unauthenticated request is rejected before the handler runs. You can add a
group restriction for these paths with `Route.Allow`; see [Access
control](./config-access).
