REST API

Observe and control services from IDE plugins, desktop apps, and CLI tools.

The API server is embedded in the fuku process and available during fuku run. It listens on 127.0.0.1:3858 by default. 3858 spells F-U-K-U on a phone keypad.

The API answers only a loopback Host. It answers 403 to any request with an Origin header, probes included. That turns away a browser. The playground below copies a curl command and sends nothing itself.

The token is optional. When server.auth.token is set, every endpoint except /api/v1/live and /api/v1/ready requires an Authorization: Bearer <token> header.

FieldDescription
server.listenLoopback TCP address to bind. Default 127.0.0.1:3858. "" or none turns the API off, as does FUKU_API_DISABLED=1
server.auth.tokenOptional. When set, the bearer token every endpoint except the probes requires
fuku.yaml
server:
  listen: "127.0.0.1:3858"
  auth:
    token: "my-dev-token"
GET/api/v1/live

Liveness probe. Returns 200 when the API server is reachable, along with the product name, the instance identifier and a fingerprint of the project directory. The identifier is new on every start, and the fingerprint is the first 16 hex characters of the SHA-256 of the path, so a caller that knows its own directory can check for a match without the path being exposed. No authentication required.

Response 200
{
  "status": "alive",
  "product": "fuku",
  "instance": "1f0c6e4a-2b8d-4c3e-9a7f-5d6b8c0e1a24",
  "fingerprint": "3f2a9c1d8b4e6072"
}
GET/api/v1/ready

Readiness probe. Returns 200 once the runtime store has received profile data, 503 before that. No authentication required.

Response 200
{ "status": "ready" }
Response 503
{ "status": "not ready" }
GET/api/v1/status

Returns fuku instance information: version, instance identifier, project directory, profile, phase, uptime, and service counts.

Response 200
{
  "version": "0.22.0",
  "instance": "1f0c6e4a-2b8d-4c3e-9a7f-5d6b8c0e1a24",
  "project": "/Users/dev/projects/shop",
  "profile": "default",
  "phase": "running",
  "uptime": 3600,
  "services": {
    "total": 8,
    "pending": 0,
    "starting": 0,
    "running": 6,
    "stopping": 0,
    "restarting": 0,
    "stopped": 1,
    "failed": 1
  }
}
Response 401
{ "error": "unauthorized" }
GET/api/v1/services

Returns all services in the active profile, ordered by tier then name.

Response 200
{
  "services": [
    {
      "id": "550e8400-...",
      "name": "api-gateway",
      "tier": "foundation",
      "status": "running",
      "watching": true,
      "pid": 12345,
      "cpu": 2.4,
      "memory": 67108864,
      "uptime": 3600
    }
  ]
}
Response 401
{ "error": "unauthorized" }
GET/api/v1/services/:id

Returns a single service by UUID.

Response 200
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "api-gateway",
  "tier": "foundation",
  "status": "running",
  "watching": true,
  "pid": 12345,
  "cpu": 2.4,
  "memory": 67108864,
  "uptime": 3600
}
Response 401
{ "error": "unauthorized" }
Response 404
{ "error": "service not found" }
POST/api/v1/services/:id/start

Starts a stopped or failed service while the instance starts up or runs. Asynchronous – poll GET /services/:id for completion.

Response 202
{
  "id": "550e8400-...",
  "name": "api-gateway",
  "action": "start",
  "status": "starting"
}
Response 401
{ "error": "unauthorized" }
Response 404
{ "error": "service not found" }
Response 409
{ "error": "service cannot be started" }
Response 409
{ "error": "instance is not accepting actions" }
Response 500
{ "error": "instance is overloaded" }
POST/api/v1/services/:id/stop

Stops a running service while the instance starts up or runs. Asynchronous – poll GET /services/:id for completion.

Response 202
{
  "id": "550e8400-...",
  "name": "api-gateway",
  "action": "stop",
  "status": "stopping"
}
Response 401
{ "error": "unauthorized" }
Response 404
{ "error": "service not found" }
Response 409
{ "error": "service is not running" }
Response 409
{ "error": "instance is not accepting actions" }
Response 500
{ "error": "instance is overloaded" }
POST/api/v1/services/:id/restart

Restarts a running, stopped, or failed service while the instance starts up or runs. Asynchronous – poll GET /services/:id for completion.

Response 202
{
  "id": "550e8400-...",
  "name": "api-gateway",
  "action": "restart",
  "status": "restarting"
}
Response 401
{ "error": "unauthorized" }
Response 404
{ "error": "service not found" }
Response 409
{ "error": "service cannot be restarted" }
Response 409
{ "error": "instance is not accepting actions" }
Response 500
{ "error": "instance is overloaded" }
ERRCommon Errors
StatusErrorWhen
401unauthorizedThe config sets a token and the request lacks it or sends a wrong one
403forbiddenThe Host is not loopback or the request carries an Origin header
404service not foundUnknown UUID
409service cannot be startedStart on a running or pending service, or one busy with another action
409service is not runningStop on a service that is not running, or one busy with another action
409service cannot be restartedRestart on a pending service, or one busy with another action
409instance is not accepting actionsAction before the profile is resolved or during shutdown
500instance is overloadedThe command queue is full. The instance shuts down and the run exits 1