2026-08-15 18:37:30 +02:00
|
|
|
# API Reference
|
|
|
|
|
|
|
|
|
|
Base URL: `http://<server.host>:<server.port>` (default `http://127.0.0.1:4173`).
|
|
|
|
|
|
|
|
|
|
When `auth.enabled: true`, every endpoint below except `/api/healthz`, `/api/auth/login`, and
|
|
|
|
|
`/api/auth/session` requires either a valid session cookie or an `Authorization: Bearer <token>`
|
|
|
|
|
header using a token from `triggershell users add-token`.
|
|
|
|
|
|
2026-08-16 12:29:55 +02:00
|
|
|
`triggershell run <scriptId>` is a first-party client of this exact REST + WS contract (see
|
|
|
|
|
[Running scripts from the CLI](../README.md#running-scripts-from-the-cli)) - nothing below is
|
|
|
|
|
CLI-specific.
|
|
|
|
|
|
2026-08-15 18:37:30 +02:00
|
|
|
## Auth
|
|
|
|
|
|
|
|
|
|
### `POST /api/auth/login`
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
curl -c cookies.txt -X POST http://127.0.0.1:4173/api/auth/login \
|
|
|
|
|
-H "Content-Type: application/json" \
|
|
|
|
|
-d '{"username":"admin","password":"..."}'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`200 {"user": {"username": "admin"}}` on success (sets the session cookie), `401` on bad
|
|
|
|
|
credentials, `429` if rate-limited.
|
|
|
|
|
|
|
|
|
|
### `POST /api/auth/logout`
|
|
|
|
|
|
|
|
|
|
`204` — clears the session.
|
|
|
|
|
|
|
|
|
|
### `GET /api/auth/session`
|
|
|
|
|
|
|
|
|
|
`200 {"authRequired": bool, "authenticated": bool, "user": {"username": string} | null}`
|
|
|
|
|
|
|
|
|
|
## Scripts
|
|
|
|
|
|
|
|
|
|
### `GET /api/scripts`
|
|
|
|
|
|
|
|
|
|
`200 {"scripts": [{"id", "name", "description"}]}`
|
|
|
|
|
|
|
|
|
|
### `GET /api/scripts/:scriptId`
|
|
|
|
|
|
|
|
|
|
Full schema for one script, including resolved UI `control` per variable and secret defaults
|
|
|
|
|
stripped:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
curl -b cookies.txt http://127.0.0.1:4173/api/scripts/deploy-service
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`404` if not found.
|
|
|
|
|
|
|
|
|
|
### `POST /api/scripts/:scriptId/runs`
|
|
|
|
|
|
|
|
|
|
Starts a run.
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
curl -b cookies.txt -X POST http://127.0.0.1:4173/api/scripts/deploy-service/runs \
|
|
|
|
|
-H "Content-Type: application/json" \
|
|
|
|
|
-d '{"variables": {"environment": "staging", "replicas": 2, "dryRun": true}}'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`201 {"runId": string, "status": "queued"}` on success. `400 {"error", "fieldErrors"}` if the
|
|
|
|
|
variables fail validation (the same Zod schema the UI form uses). `404` if the script doesn't exist.
|
|
|
|
|
|
|
|
|
|
## Runs
|
|
|
|
|
|
|
|
|
|
### `GET /api/runs`
|
|
|
|
|
|
|
|
|
|
Query params: `scriptId`, `status` (one of `queued|running|succeeded|failed|cancelled|timed_out|interrupted`),
|
|
|
|
|
`limit` (default 50, max 200), `cursor` (offset, from the previous page's `nextCursor`).
|
|
|
|
|
|
|
|
|
|
`200 {"runs": [...], "nextCursor": string | null}`
|
|
|
|
|
|
|
|
|
|
### `GET /api/runs/:runId`
|
|
|
|
|
|
|
|
|
|
The full run record (status, variables with secrets redacted, resolved command, timestamps, exit
|
|
|
|
|
code). `404` if not found.
|
|
|
|
|
|
|
|
|
|
### `POST /api/runs/:runId/cancel`
|
|
|
|
|
|
2026-08-16 13:55:25 +02:00
|
|
|
`202 {"status": "cancelling"}`. `409` if the run already finished, or if it isn't tracked by _this_
|
2026-08-15 18:37:30 +02:00
|
|
|
server process (e.g. after a restart — see "orphaned runs" in `docs/ARCHITECTURE.md`).
|
|
|
|
|
|
|
|
|
|
### `GET /api/runs/:runId/logs`
|
|
|
|
|
|
|
|
|
|
Plain-text log output. Query params: `tail=<N>` (last N lines only), `download=1` (sets
|
|
|
|
|
`Content-Disposition: attachment`).
|
|
|
|
|
|
|
|
|
|
## WebSocket: `/ws/runs`
|
|
|
|
|
|
|
|
|
|
Auth: session cookie, or `?token=<api-token>` for non-browser clients (the upgrade request has no
|
|
|
|
|
`Authorization` header support, since it's a plain HTTP upgrade).
|
|
|
|
|
|
|
|
|
|
Client → server messages:
|
|
|
|
|
|
|
|
|
|
```jsonc
|
|
|
|
|
{ "type": "subscribe", "runId": "..." }
|
|
|
|
|
{ "type": "unsubscribe", "runId": "..." }
|
|
|
|
|
{ "type": "cancel", "runId": "..." }
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Server → client messages:
|
|
|
|
|
|
|
|
|
|
```jsonc
|
|
|
|
|
{ "type": "output", "runId": "...", "stream": "stdout" | "stderr", "chunk": "...", "seq": 0, "ts": 0 }
|
|
|
|
|
{ "type": "status", "runId": "...", "status": "running", "exitCode": null, "ts": 0 }
|
|
|
|
|
{ "type": "error", "runId": "...", "message": "..." }
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
A client only receives messages for runs it has subscribed to.
|