Files
valknarandClaude Sonnet 5 14158047ac
Release / release (push) Successful in 1m6s
Make the README link in docs/API.md absolute
The docs viewer serves docs/*.md at /docs/<slug> but doesn't ship
README.md as a route, so the relative ../README.md link resolved to
a dead /README.md path in the rendered web UI. Point it at the file's
Gitea URL instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 10:01:00 +02:00

3.4 KiB

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.

triggershell run <scriptId> is a first-party client of this exact REST + WS contract (see Running scripts from the CLI) - nothing below is CLI-specific.

Auth

POST /api/auth/login

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:

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.

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

202 {"status": "cancelling"}. 409 if the run already finished, or if it isn't tracked by this 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:

{ "type": "subscribe", "runId": "..." }
{ "type": "unsubscribe", "runId": "..." }
{ "type": "cancel", "runId": "..." }

Server → client messages:

{ "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.