/api/* and one Server-Sent Events stream for Turn execution. The canonical schema lives in openapi.yaml; this page is a high-level map.
Fleet uses one deterministic local User and Workspace scope. It accepts no Authorization header or caller-supplied identity headers. There is no /api/v1 prefix, no WebSocket execution surface, no optimization/evaluation API, no runtime-admin API, no caller-selected BYOK profile API, and no public Artifact creation endpoint.
Backend launchers default to binding 127.0.0.1 and reject non-loopback hosts unless --allow-non-loopback-bind is passed. The /api/settings endpoint is a separate local administration surface: it rejects non-loopback clients even when the API has been explicitly bound to another interface.
Endpoint map
Turn creation
POST /api/sessions/{session_id}/turns executes exactly one Turn against a fresh native dspy.RLM. Idempotency is mandatory.
Required headers:
Request body:
Explicit
skill_selections become authoritative for the Turn and are folded into its idempotency fingerprint. Omitting skill_selections supplies the full bounded catalog to the RLM and permits it to progressively load up to four advertised Skills. Providing selections preloads those exact versions and restricts loading to that set.
Structurally malformed selections fail pre-stream with 422 invalid_skill_selection. Catalog-rejected selections (missing, unauthorized, or version-mismatched) resolve during in-stream Turn opening and surface as a stream error chunk with the generic message Invalid Skill selection. Both paths avoid revealing hidden catalog entries.
Streaming contract
The response opens the AI SDK UI message stream immediately instead of holding headers until preparation finishes. Transport200 no longer implies a successful Turn; the Run id lives in the start chunk metadata.
While the Turn claim and preparation resolve, the server emits a transient data-status chunk:
runtime.heartbeat_seconds (configured in config/fleet.toml) until coordinator.open completes. Prelude chunks are client-facing keep-alives only; they never enter durable Turn history or the event log and may repeat.
After opening, exactly one of three closings applies:
- Success streams Runtime Events, ends with
finish, then[DONE]. - Claim or preparation failures close the stream with
error+finishchunks that map to the same messages the old prepare-before-headers boundary surfaced as HTTP statuses (Session not found,A Turn is already running,Idempotency key input mismatch,Invalid Skill selection,Turn preparation timed out,Turn is unavailable,Invalid request), then[DONE]. - Run cancellation ends the live stream with one terminal
abortchunk and nothing after it. Nofinish, nodata-usage, no checkpoint metadata.
GET /api/sessions/{session_id}/turns shows the attempt: the original user input plus one assistant message carrying only a cancelled data-status part, observed usage, and the closed text Turn cancelled. Cancelled tombstones never contain reasoning, code, output, or Tool evidence parts.
Example
Run cancellation
PUT /api/runs/{run_id}/cancellation requests durable cancellation of an owned Run. The active stream closes with a single abort chunk. A bounded tombstone is written after settlement so history remains consistent.
Files API
GET /api/files, GET /api/files/stat, GET /api/files/content, PUT /api/files/content, POST /api/files/append, PATCH /api/files/content, and DELETE /api/files/content operate on the process-local Workspace files/ root. Callers cannot select a Workspace or address Daytona Volume, mount, Sandbox, Attachment, Artifact, Session, or Run identifiers through this API.
The Files API has no rename operation and accepts an optional current SHA-256 on overwrite, append, delete, and patch. Stale preconditions return 409.
DELETE /api/files/contentremoves one file or one empty directory. Non-empty directories return409.PATCH /api/files/contentapplies one unique find/replace whoseoldtext must occur exactly once. Absent or ambiguous matches return409. The response returns the fresh content checksum for precondition chaining.
Attachments and Artifacts
POST /api/attachments uploads one durable Attachment and returns its id for future Turn requests.
GET /api/artifacts/{artifact_id} and GET /api/artifacts/{artifact_id}/content return committed metadata and verified bytes. There is no POST /api/artifacts. Artifacts become public only when the host-mediated create_artifact produces a private candidate that is then promoted through Turn Commit.
Volume tree
GET /api/volume/tree (Daytona only) returns a bounded, read-only view of relative paths within the mounted Workspace Volume. It is a process-local logical view, not a general-purpose Sandbox filesystem browser.
Skills
GET /api/skills returns bounded Skill Cards for the five bundled system Skills (data-analysis, dspy-rlm, long-context, report-builder, workspace-files). GET /api/skills/{skill_id} returns one Skill Card by id.
Selecting a Skill on a Turn preloads that exact expected_version and restricts progressive load_skill calls to the authorized set.
Local settings
GET /api/settings and PATCH /api/settings read and revision-update the non-secret config/fleet.toml policy. This endpoint rejects any non-loopback client — including when the main API is bound to another interface — and never reads or returns .env values, provider credentials, or database URLs. Saved policy applies only after Fleet is restarted.
Source of truth
- Routes:
src/fleet_rlm/api/routes/ - Turn coordinator:
src/fleet_rlm/chat/turn_coordinator.py - SSE stream projection:
src/fleet_rlm/api/sse.pyandapi/ui_stream.py - Canonical schema:
openapi.yaml