Skip to main content

REST API

swamp serve exposes a REST API alongside its WebSocket interface. This page documents the available HTTP endpoints.

Authentication

REST API endpoints take a Bearer token in the Authorization header. The token is the same credential used for WebSocket authentication.

Authorization: Bearer <token>

The two health endpoints accept any valid server token and narrow what they return to what the token may read. Every other endpoint on this page except GET / requires admin (admin on access:*) and answers 403 without it.

When --auth-mode is none (deprecated), no token is required.

See Monitor Server Health for how to mint a monitoring token.

Server Info Endpoint

GET /

Returns a JSON object describing the server instance and its capabilities. This is the unauthenticated discovery endpoint — it does not require a Bearer token.

Response body

Field Type Description
name string Server identifier.
version string Swamp version running on the server.
instanceId string Unique identifier for this server instance, stable for the lifetime of the process.
remoteOnly bool Whether the server is running in remote-only mode. When true, all steps must declare placement for dispatch.

Response

Status Condition
200 Server info returned.

Example

curl https://swamp.example.com/
{
  "name": "swamp-serve",
  "version": "20260818.234252.0",
  "instanceId": "a1b2c3d4",
  "remoteOnly": true
}

Health Monitoring Endpoints

GET /api/v1/health

Returns a point-in-time JSON snapshot of node health. Any valid server token may read it; see What each token sees.

Response body

Field Type Description
instanceId string Unique identifier for the server instance.
deploymentMode string Deployment mode: local, durable, or durable (limited).
remoteOnly bool Whether the server is running in remote-only mode. When true, all steps must declare placement.
uptimeMs number Milliseconds since the server started.
ready bool Whether the instance is accepting work.
activeRuns array Active runs — each entry has runId, kind, resourceName, durationMs, principalId.
metrics object Sliding-window counters: windowMs (5 min), completions, failures, cancellations, throughputPerMinute, and latency (p50, p95, p99, or null with no completed runs).
workers array Each entry has name, instanceUuid, labels, platform, arch, swampVersion, status, connected, capacity, activeDispatchIds. Status is idle, busy, unverified, or draining.
scheduling object enabled flag and a schedules array — each entry has workflowId, workflowName, cronExpression, nextRun, running.
webhooks array Registered webhooks — each entry has route, workflow, scheme.
components array Health of internal subsystems (datastore, vault). Each entry has name, healthy, message, latencyMs, details.

What each token sees

An admin token sees the full snapshot. Any other token sees:

  • activeRuns, scheduling.schedules and webhooks narrowed to the models and workflows it may read (see Authorization), with principalId set to null on every run
  • workers and components empty
  • instance fields (instanceId, deploymentMode, remoteOnly, ready), uptimeMs and metrics in full

One collected snapshot serves every reader for up to one second, so a snapshot can be up to a second old. After a tag edit that changes which grants match a model or workflow, a non-admin reader's view can take up to five seconds to follow. Grant changes apply at once.

Response

Status Condition
200 Health snapshot returned.
401 Missing or invalid Bearer token.
429 Request rate limit reached for the client or token; honour Retry-After.

Example

curl https://swamp.example.com/api/v1/health \
  -H "Authorization: Bearer health-monitor.secret"

GET /api/v1/health/stream

Server-Sent Events stream that pushes health snapshots at a configurable interval.

An initial snapshot is sent immediately on connect, then at the configured interval. Supports Last-Event-ID for resumable connections. Any valid server token may open a stream, and each snapshot is narrowed as described in What each token sees.

A token may hold at most 10 open streams, counted across every mint of the token name, and its principal at most 20 across all of its tokens. A stream beyond either limit is refused with 429.

Query parameters

Parameter Type Default Description
interval number 5000 Push frequency in milliseconds (min 1000, max 60000).

SSE format

id: 1
event: health
data: {"instanceId":"...","uptime":3600,...}

id: 2
event: health
data: {"instanceId":"...","uptimeMs":3605000,...}

The stream is a token session. When its token is revoked, rotated, or expires, or its principal loses access, the server sends a final session-ended event and closes the stream. The event has no id, and its data holds a close code and a reason:

event: session-ended
data: {"code":4003,"reason":"Session revoked: token revoked"}
Code Meaning
4002 The token expired. Mint a new token.
4003 The token was revoked, rotated, or deleted, or the principal lost access.
4004 The principal's group or collective membership changed. The token still works; reconnect.

A revoke on this instance ends the stream at once. A revoke on another instance takes effect at the next revalidation pass: up to 30 seconds plus the datastore poll interval. A close caused by the token itself — revoked, rotated, expired or deleted — records an auth.session.terminated audit event, as for WebSocket sessions. Consumers that ignore unknown event names are unaffected.

Headers

Includes X-Accel-Buffering: no for nginx reverse proxy compatibility.

Response

Status Condition
200 SSE stream opened.
401 Missing or invalid Bearer token.
429 Stream limit reached (10 per token name, 20 per principal), with Retry-After: 30; or the request rate limit was reached.

Example

curl -N https://swamp.example.com/api/v1/health/stream?interval=10000 \
  -H "Authorization: Bearer health-monitor.secret"

To resume after a disconnect:

curl -N https://swamp.example.com/api/v1/health/stream \
  -H "Authorization: Bearer health-monitor.secret" \
  -H "Last-Event-ID: 42"

GET /internal/runs

Returns all run records from the SQLite-backed RunTrackerStore, including completed, failed, and cancelled runs with full metadata.

Disabled by default. Enable with any of:

  • --enable-internal-api flag
  • enable-internal-api: true in the serve config file
  • SWAMP_ENABLE_INTERNAL_API=true environment variable

Returns 404 when not enabled.

Response

Status Condition
200 Run records returned.
401 Missing or invalid Bearer token.
403 The token is not admin.
404 Internal API not enabled (--enable-internal-api required).

Example

curl https://swamp.example.com/internal/runs \
  -H "Authorization: Bearer paul-token.secret"

Cancel Endpoints

Cancel a running execution via HTTP. These endpoints complement the CLI commands (swamp workflow cancel, swamp model cancel) for use by external tooling, CI/CD pipelines, or custom dashboards.

POST /api/v1/cancel/:type/:id

Cancel a single running execution by type and ID.

Parameter Value Description
:type workflow-run or method-run The execution type to cancel.
:id string The execution's run ID.

Response

Status Body Condition
200 { "status": "cancelled", "executionType": "...", "executionId": "..." } The execution was confirmed stopped — deregistered within the grace period.
200 { "status": "cancellation_requested", "executionType": "...", "executionId": "..." } The abort signal was delivered but the execution is still active — it has not yet deregistered within the grace period.
401 "Unauthorized: token required" or "Unauthorized" Missing or invalid Bearer token.
403 { "status": "error", "message": "Access denied: cancel requires admin permission" } The token is not admin.
404 { "status": "not_found", "message": "..." } No active execution with the given type/ID.

Example

curl -X POST https://swamp.example.com/api/v1/cancel/workflow-run/3f8a2b1c \
  -H "Authorization: Bearer paul-token.secret"

POST /api/v1/cancel

Cancel all running executions, optionally filtered by type.

Request body (optional)

Field Type Description
executionType string Filter by type: workflow-run or method-run. Omit to cancel all.
{ "executionType": "workflow-run" }

Response

Status Body Condition
200 { "status": "cancellation_requested", "count": <number> } Abort signals delivered. Returns the count of runs cancellation was requested for.
400 { "status": "error", "message": "executionType must be 'workflow-run' or 'method-run'" } Invalid executionType value.
401 "Unauthorized: token required" or "Unauthorized" Missing or invalid Bearer token.
403 { "status": "error", "message": "Access denied: cancel requires admin permission" } The token is not admin.

Example

# Cancel all running executions
curl -X POST https://swamp.example.com/api/v1/cancel \
  -H "Authorization: Bearer paul-token.secret"

# Cancel only workflow runs
curl -X POST https://swamp.example.com/api/v1/cancel \
  -H "Authorization: Bearer paul-token.secret" \
  -H "Content-Type: application/json" \
  -d '{"executionType": "workflow-run"}'