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

# Read endpoints

> All public GET endpoints — no authentication required.

All `GET` routes are public. No API key is needed. Responses are JSON unless otherwise noted.

**Base URL:** `http://your-server:6767`

***

## GET /

Returns the plain text output of `servreport.sh` — the same human-readable report you would see by running the script on the server directly.

```bash theme={null}
curl http://your-server:6767/
```

**Response** — `text/plain`

```text theme={null}
=== PopLock Server Report ===
...
```

***

## GET /api

Returns the endpoint index with service name and version.

```bash theme={null}
curl http://your-server:6767/api
```

**Response**

```json theme={null}
{
  "ok": true,
  "service": "PopLock API",
  "version": "1.0.0",
  "endpoints": [
    { "method": "GET",  "route": "/",                    "auth_required": false },
    { "method": "GET",  "route": "/api/status",          "auth_required": false },
    { "method": "POST", "route": "/api/server/start",    "auth_required": true  }
  ]
}
```

<ResponseField name="ok" type="boolean" required>
  `true` on success.
</ResponseField>

<ResponseField name="service" type="string" required>
  Always `"PopLock API"`.
</ResponseField>

<ResponseField name="version" type="string" required>
  API version string, e.g. `"1.0.0"`.
</ResponseField>

<ResponseField name="endpoints" type="object[]" required>
  Array of all registered routes. Each entry includes `method`, `route`, and `auth_required`.
</ResponseField>

***

## GET /api/status

Returns whether the Minecraft server process is running. When online, also returns the PID, uptime, memory usage, and version.

```bash theme={null}
curl http://your-server:6767/api/status
```

**Response — server online**

```json theme={null}
{
  "ok": true,
  "online": true,
  "pid": 12345,
  "uptime": "0:15:30",
  "memory": "12.3%",
  "version": "1.21.4-123"
}
```

**Response — server offline**

```json theme={null}
{
  "ok": true,
  "online": false
}
```

<ResponseField name="ok" type="boolean" required>
  `true` on success.
</ResponseField>

<ResponseField name="online" type="boolean" required>
  `true` if the server Java process is currently running.
</ResponseField>

<ResponseField name="pid" type="number">
  Process ID of the running server. Only present when `online` is `true`.
</ResponseField>

<ResponseField name="uptime" type="string">
  Elapsed time since process start in `H:MM:SS` format. Only present when `online` is `true`.
</ResponseField>

<ResponseField name="memory" type="string">
  Memory usage as a percentage of total system memory (e.g. `"12.3%"`). Only present when `online` is `true`.
</ResponseField>

<ResponseField name="version" type="string">
  Minecraft server version from `version_history.json` (e.g. `"1.21.4-123"`). Only present when `online` is `true` and the file is readable.
</ResponseField>

***

## GET /api/players/online

Returns the list of players currently connected to the server. Player presence is determined by parsing join and leave events from `latest.log`.

<Note>
  If the server is offline, `online` is `false` and `players` is an empty array — no log parsing is attempted.
</Note>

```bash theme={null}
curl http://your-server:6767/api/players/online
```

**Response**

```json theme={null}
{
  "ok": true,
  "online": true,
  "count": 2,
  "players": ["PlayerOne", "PlayerTwo"]
}
```

<ResponseField name="ok" type="boolean" required>
  `true` on success.
</ResponseField>

<ResponseField name="online" type="boolean" required>
  `true` if the server process is running.
</ResponseField>

<ResponseField name="count" type="number">
  Number of players currently online. Only present when `online` is `true`.
</ResponseField>

<ResponseField name="players" type="string[]" required>
  Array of online player names. Empty array when the server is offline.
</ResponseField>

***

## GET /api/players/whitelist

Returns the full contents of `whitelist.json` as parsed JSON.

```bash theme={null}
curl http://your-server:6767/api/players/whitelist
```

**Response**

```json theme={null}
{
  "ok": true,
  "count": 5,
  "whitelist": [
    { "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "name": "PlayerOne" }
  ]
}
```

<ResponseField name="ok" type="boolean" required>
  `true` on success.
</ResponseField>

<ResponseField name="count" type="number" required>
  Total number of whitelisted players.
</ResponseField>

<ResponseField name="whitelist" type="object[]" required>
  Array of whitelist entries, each with `uuid` and `name` fields, exactly as stored in `whitelist.json`.
</ResponseField>

***

## GET /api/logs/latest

Returns the last N lines of `latest.log`.

<ParamField query="lines" type="number" default="200">
  Number of lines to return. Maximum is `2000`. Defaults to `200` if omitted.
</ParamField>

```bash theme={null}
curl "http://your-server:6767/api/logs/latest?lines=100"
```

**Response**

```json theme={null}
{
  "ok": true,
  "file": "latest.log",
  "lines": [
    "[12:00:01] [Server thread/INFO]: Starting minecraft server version 1.21.4",
    "[12:00:05] [Server thread/INFO]: Done (3.412s)! For help, type \"help\""
  ]
}
```

<ResponseField name="ok" type="boolean" required>
  `true` on success.
</ResponseField>

<ResponseField name="file" type="string" required>
  Always `"latest.log"`.
</ResponseField>

<ResponseField name="lines" type="string[]" required>
  Array of log lines, oldest first.
</ResponseField>

***

## GET /api/logs/snapshot

Returns the last N lines of the snapshot cron log at `/var/log/minecraft_snapshot.log`.

<ParamField query="lines" type="number" default="200">
  Number of lines to return. Maximum is `2000`. Defaults to `200` if omitted.
</ParamField>

```bash theme={null}
curl "http://your-server:6767/api/logs/snapshot?lines=50"
```

**Response**

```json theme={null}
{
  "ok": true,
  "file": "/var/log/minecraft_snapshot.log",
  "lines": [
    "[2024-01-15 23:00:01] Starting snapshot backup...",
    "[2024-01-15 23:00:12] Snapshot complete: snapshot_20240115_230012.tar.gz"
  ]
}
```

<ResponseField name="ok" type="boolean" required>
  `true` on success.
</ResponseField>

<ResponseField name="file" type="string" required>
  Always `"/var/log/minecraft_snapshot.log"`.
</ResponseField>

<ResponseField name="lines" type="string[]" required>
  Array of log lines, oldest first.
</ResponseField>

***

## GET /api/backups

Lists all `.tar.gz` files in the backup directory, sorted by creation date with the newest first.

```bash theme={null}
curl http://your-server:6767/api/backups
```

**Response**

```json theme={null}
{
  "ok": true,
  "count": 7,
  "backups": [
    {
      "name": "snapshot_20240115_230012.tar.gz",
      "type": "snapshot",
      "size": "1.20 GB",
      "bytes": 1234567890,
      "created": "2024-01-15T23:00:12.000Z"
    }
  ]
}
```

Backup type is inferred from the filename prefix:

| Prefix              | Type           |
| ------------------- | -------------- |
| `snapshot_`         | `snapshot`     |
| `minecraft_backup_` | `full_backup`  |
| `restore_undo`      | `restore_undo` |
| anything else       | `archive`      |

<ResponseField name="ok" type="boolean" required>
  `true` on success.
</ResponseField>

<ResponseField name="count" type="number" required>
  Total number of backup files found.
</ResponseField>

<ResponseField name="backups" type="object[]" required>
  Array of backup entries sorted newest first.

  <Expandable title="backup object fields">
    <ResponseField name="name" type="string" required>
      Filename of the backup archive.
    </ResponseField>

    <ResponseField name="type" type="string" required>
      Inferred type: `snapshot`, `full_backup`, `restore_undo`, or `archive`.
    </ResponseField>

    <ResponseField name="size" type="string" required>
      Human-readable file size (e.g. `"1.20 GB"`).
    </ResponseField>

    <ResponseField name="bytes" type="number" required>
      Raw file size in bytes.
    </ResponseField>

    <ResponseField name="created" type="string" required>
      ISO 8601 timestamp derived from the file's last-modified time.
    </ResponseField>
  </Expandable>
</ResponseField>

***

## GET /api/properties

Returns the contents of `server.properties` parsed as a flat key/value object. Comment lines and blank lines are excluded.

```bash theme={null}
curl http://your-server:6767/api/properties
```

**Response**

```json theme={null}
{
  "ok": true,
  "properties": {
    "server-port": "25565",
    "max-players": "20",
    "level-name": "world",
    "difficulty": "normal"
  }
}
```

<ResponseField name="ok" type="boolean" required>
  `true` on success.
</ResponseField>

<ResponseField name="properties" type="object" required>
  All non-comment key/value pairs from `server.properties`. All values are strings.
</ResponseField>

***

## GET /api/report

Returns the `servreport.sh` output as a JSON-wrapped string rather than plain text. Useful when you need to parse or forward the report programmatically.

```bash theme={null}
curl http://your-server:6767/api/report
```

**Response**

```json theme={null}
{
  "ok": true,
  "report": "=== PopLock Server Report ===\n..."
}
```

<ResponseField name="ok" type="boolean" required>
  `true` on success.
</ResponseField>

<ResponseField name="report" type="string" required>
  Full plain text output of `servreport.sh`, with newlines preserved.
</ResponseField>
