# Execution server

> The langoost server HTTP API — POST /execute to run inline source or a .goost file, GET /health for status, and DELETE /cache to clear the module cache.

# Execution server

`langoost server` runs Langoost as a persistent daemon that executes scripts
over HTTP. The process stays warm and caches compiled modules, so there's no
per-request cold start; each execution still runs in its own isolated VM.

> This is different from [`http.serve`](/docs/http-server) and the
> [web libraries](/docs/web-libraries), which let *your* script handle HTTP
> requests. The execution server is the host that *runs* scripts on demand.

## Starting it

The server binds **loopback (`127.0.0.1`) by default**, so it's private to the
machine. Exposing it publicly (`--bind 0.0.0.0`) requires an auth token.

```
$ langoost server                                        # local only
$ langoost server --bind 0.0.0.0 --auth-token "$TOKEN"   # public, authenticated
```

| Flag | Default | Description |
| --- | --- | --- |
| `--bind` | `127.0.0.1` | Interface to bind; `0.0.0.0` exposes it publicly |
| `--port` | `8080` | Port to listen on |
| `--auth-token` | `$LANGOOST_AUTH_TOKEN` | Bearer token required for `/execute` and `/cache` |
| `--dir` | `.` | Directory searched for `.goost` files |
| `--max-source-bytes` | `1 MiB` | Cap on submitted source/file size |
| `--allow-stdlib` | all | Comma-separated stdlib allowlist (empty = allow all) |
| `--pprof :ADDR` | off | Expose Go's `net/http/pprof` |

## Authentication

When an `--auth-token` is set, `POST /execute` and `DELETE /cache` require a
matching `Authorization: Bearer <token>` header (`GET /health` stays open). A
public bind without a token is refused unless you pass the explicit
`--unsafe-allow-no-auth` escape hatch — never do that in production.

```bash
curl -s localhost:8080/execute \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"source": "print(1 + 1)"}'
```

## POST /execute

Run a script. The JSON body selects what to run:

| Field | Type | Description |
| --- | --- | --- |
| `source` | string | Inline Langoost source to compile and run |
| `file` | string | Path to a `.goost` file to run (resolved under `--dir`) |
| `file_name` | string | Name used for error messages / source mapping |
| `fn` | string | Optional: a function to call after the script loads |

Provide either `source` or `file`. On success the response is **200** with the
captured stdout, the script's (or function's) return value, and the timing:

```bash
curl -s localhost:8080/execute -d '{
  "source": "let x = 21\nprint(x * 2)"
}'
```

```json
{
  "output": "42\n",
  "return": null,
  "duration_ms": 1
}
```

Call a specific function in a file:

```bash
curl -s localhost:8080/execute -d '{
  "file": "handlers.goost",
  "fn": "handle"
}'
```

If the script throws or fails to compile, the response is **422** with the
error, any output produced before the failure, and the duration:

```json
{
  "error": "handlers.goost:7: undefined variable \"x\"",
  "output": "",
  "duration_ms": 0
}
```

Malformed JSON returns **400**; a non-POST method returns **405**.

## GET /health

Liveness and status, including how many modules are currently cached:

```bash
curl -s localhost:8080/health
```

```json
{
  "status": "ok",
  "version": "0.1.0",
  "cached_modules": 3
}
```

## DELETE /cache

Clear the compiled-module cache. Modules are recompiled on the next import —
useful during development after editing a `.goost` module that the server has
already loaded:

```bash
curl -s -X DELETE localhost:8080/cache
```

```json
{ "status": "cache cleared" }
```