openapi: "3.1.0" info: title: Fabro Run API version: "0.1.0" description: HTTP API for managing Fabro workflow run executions. tags: - name: Discovery description: API discovery and health - name: Install description: First-run browser install workflow - name: Integrations description: External provider callbacks and integration endpoints - name: Runs description: Run management operations - name: Human-in-the-Loop description: Questions, answers, and steering for runs - name: Run Outputs description: Files produced by runs - name: Run Internals description: Internal run details (stages, turns, context, configuration) - name: Workflows description: Workflow definitions and execution - name: Billing description: Token counts and billed totals - name: Insights description: SQL query editor and history - name: Models description: Available LLM models - name: Completions description: Single-turn LLM completions - name: Settings description: Platform configuration - name: System description: Server runtime, maintenance, and event streaming security: - BearerAuth: [] - SessionCookie: [] paths: # ── Discovery ──────────────────────────────────────────────────────── /: get: operationId: getRoot tags: [Discovery] summary: API Discovery description: Returns discovery URLs for the API. security: [] responses: "200": description: Discovery URLs content: application/json: schema: $ref: "#/components/schemas/RootResponse" /health: get: operationId: getHealth tags: [Discovery] summary: Health Check description: Returns service health status. Used by load balancers and monitoring. security: [] responses: "200": description: Service is healthy content: application/json: schema: $ref: "#/components/schemas/HealthResponse" /install/session: get: operationId: getInstallSession tags: [Install] summary: Get install session description: > Returns the current browser-install session snapshot. Requires the one-time install token in `Authorization: Bearer`, `?token=`, or `X-Install-Token`. security: [] responses: "200": description: Current install session state content: application/json: schema: $ref: "#/components/schemas/InstallSessionResponse" "401": description: Invalid or missing install token content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /install/llm/test: post: operationId: testInstallLlmCredentials tags: [Install] summary: Validate install LLM credentials description: Validates an LLM API key without persisting it. Requires the one-time install token. security: [] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/InstallLlmTestInput" responses: "200": description: Credentials validated successfully content: application/json: schema: $ref: "#/components/schemas/InstallLlmValidationResponse" "401": description: Invalid or missing install token content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "422": description: Credential validation failed content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /install/llm: put: operationId: putInstallLlm tags: [Install] summary: Save install LLM settings description: Records the LLM providers and API keys chosen during the browser install. Requires the one-time install token. security: [] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/InstallLlmProvidersInput" responses: "204": description: LLM settings recorded "401": description: Invalid or missing install token content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "422": description: Invalid install input content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /install/server: put: operationId: putInstallServer tags: [Install] summary: Save install server configuration description: Records the canonical server URL confirmed by the operator. Requires the one-time install token. security: [] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/InstallServerConfigInput" responses: "204": description: Server configuration recorded "401": description: Invalid or missing install token content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "422": description: Invalid canonical URL content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /install/object-store/test: post: operationId: testInstallObjectStore tags: [Install] summary: Validate install object-store configuration description: Validates the browser-install object-store selection without persisting it. Requires the one-time install token. security: [] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/InstallObjectStoreInput" responses: "200": description: Object-store configuration validated successfully content: application/json: schema: $ref: "#/components/schemas/InstallObjectStoreValidationResponse" "401": description: Invalid or missing install token content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "422": description: Object-store validation failed content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /install/object-store: put: operationId: putInstallObjectStore tags: [Install] summary: Save install object-store configuration description: Records the object-store mode selected during browser install. Requires the one-time install token. security: [] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/InstallObjectStoreInput" responses: "204": description: Object-store configuration recorded "401": description: Invalid or missing install token content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "422": description: Invalid install input content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /install/github/token/test: post: operationId: testInstallGithubToken tags: [Install] summary: Validate install GitHub token description: Validates a GitHub personal access token without persisting it. Requires the one-time install token. security: [] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/InstallGithubTokenTestInput" responses: "200": description: GitHub token validated successfully content: application/json: schema: $ref: "#/components/schemas/InstallGithubTokenTestResponse" "401": description: Invalid or missing install token content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "422": description: GitHub token validation failed content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /install/github/token: put: operationId: putInstallGithubToken tags: [Install] summary: Save install GitHub token description: Records the GitHub personal access token chosen during the browser install. Requires the one-time install token. security: [] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/InstallGithubTokenInput" responses: "204": description: GitHub token recorded "401": description: Invalid or missing install token content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "422": description: Invalid install input content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /install/github/app/manifest: post: operationId: createInstallGithubAppManifest tags: [Install] summary: Build install GitHub App manifest description: Builds the GitHub App manifest and stores the temporary callback state for the browser install. Requires the one-time install token. security: [] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/InstallGithubAppManifestInput" responses: "200": description: GitHub App manifest ready for browser handoff content: application/json: schema: $ref: "#/components/schemas/InstallGithubAppManifestResponse" "401": description: Invalid or missing install token content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "422": description: Invalid install input or missing prior steps content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /install/github/app/redirect: get: operationId: completeInstallGithubAppRedirect tags: [Install] summary: Complete install GitHub App redirect description: Manifest-conversion callback target used by GitHub during browser install. Authorized by the callback `state` query parameter rather than the install token. security: [] parameters: - name: code in: query required: true schema: type: string - name: state in: query required: true schema: type: string responses: "302": description: Browser redirected back into the install SPA "400": description: Invalid or expired GitHub App callback state content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "502": description: GitHub manifest conversion failed content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /install/finish: post: operationId: finishInstall tags: [Install] summary: Finalize browser install description: Persists settings, runtime secrets, and install outputs, then schedules the install-mode process to exit cleanly. Requires the one-time install token. security: [] responses: "202": description: Install persisted successfully; restart handoff in progress content: application/json: schema: $ref: "#/components/schemas/InstallFinishResponse" "401": description: Invalid or missing install token content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "422": description: Install session is incomplete content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "500": description: Install persistence failed content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/health/diagnostics: post: operationId: runDiagnostics tags: [Discovery] summary: Run server health diagnostics description: Probes external services and server configuration. May be slow. responses: "200": description: Diagnostics report content: application/json: schema: $ref: "#/components/schemas/DiagnosticsReport" /api/v1/openapi.json: get: operationId: getOpenApiSpec tags: [Discovery] summary: OpenAPI Specification description: Returns the OpenAPI spec as JSON. security: [] responses: "200": description: OpenAPI specification content: application/json: schema: type: object /api/v1/webhooks/github: post: operationId: receiveGithubWebhook tags: [Integrations] summary: Receive GitHub Webhook description: Receives GitHub App webhook deliveries. Requests are authenticated by `X-Hub-Signature-256`, not API bearer auth. security: [] requestBody: required: true content: application/json: schema: type: object additionalProperties: true responses: "200": description: Webhook accepted "401": description: Missing or invalid webhook signature /api/v1/user: get: operationId: getUser tags: [Discovery] summary: Current User description: Returns info about the authenticated user. responses: "200": description: User info content: application/json: schema: $ref: "#/components/schemas/UserResponse" "401": description: Not authenticated content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" # ── Runs ────────────────────────────────────────────────────────────── /api/v1/runs: get: operationId: listRuns tags: [Runs] summary: List Runs description: Returns durable run summaries from the backing store, including runs persisted before the current server boot. Archived runs are hidden by default; pass `include_archived=true` to include them in the response. parameters: - $ref: "#/components/parameters/PageLimit" - $ref: "#/components/parameters/PageOffset" - $ref: "#/components/parameters/IncludeArchived" responses: "200": description: Paginated durable run summaries content: application/json: schema: $ref: "#/components/schemas/PaginatedRunList" post: operationId: createRun tags: [Runs] summary: Create Run description: Creates a new workflow run in `submitted` status from a self-contained manifest. requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/RunManifest" responses: "201": description: Run created content: application/json: schema: $ref: "#/components/schemas/RunStatusResponse" "400": description: Invalid Graphviz source content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/resolve: get: operationId: resolveRun tags: [Runs] summary: Resolve Run Selector description: Resolves a run selector to one durable run summary using server-owned selector semantics. parameters: - $ref: "#/components/parameters/RunSelector" responses: "200": description: Durable run summary content: application/json: schema: $ref: "#/components/schemas/StoreRunSummary" "400": description: Selector is invalid or ambiguous content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "404": description: No run matched the selector content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/preflight: post: operationId: runPreflight tags: [Runs] summary: Validate Workflow Manifest description: Validates a workflow manifest without creating a run. requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/RunManifest" responses: "200": description: Preflight report content: application/json: schema: $ref: "#/components/schemas/PreflightResponse" "400": description: Invalid manifest or workflow content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/graph/render: post: operationId: renderWorkflowGraph tags: [Runs] summary: Render Workflow Graph description: Validates and renders a workflow manifest as SVG without creating a run. requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/RenderWorkflowGraphRequest" responses: "200": description: Rendered graph image content: image/svg+xml: schema: type: string format: binary "400": description: Invalid manifest or workflow content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}: get: operationId: retrieveRun tags: [Runs] summary: Retrieve Run description: Returns the durable run summary for a run. parameters: - $ref: "#/components/parameters/RunId" responses: "200": description: Durable run summary content: application/json: schema: $ref: "#/components/schemas/StoreRunSummary" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" delete: operationId: deleteRun tags: [Runs] summary: Delete Run description: Deletes durable store state for a run. This does not remove any local run directory. Active runs require `force=true`. parameters: - $ref: "#/components/parameters/RunId" - $ref: "#/components/parameters/ForceRunDelete" responses: "204": description: Run deleted or already absent "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "409": description: Run is active and requires `force=true` content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/cancel: post: operationId: cancelRun tags: [Runs] summary: Cancel Run description: Cancels a running or queued run. Returns 409 if the run has already completed or been cancelled. parameters: - $ref: "#/components/parameters/RunId" responses: "200": description: Run cancelled content: application/json: schema: $ref: "#/components/schemas/RunStatusResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "409": description: Run is not running content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/start: post: operationId: startRun tags: [Runs] summary: Start Run description: Starts a submitted run, queuing it for execution. Provide `resume=true` to resume an interrupted run from checkpoint. Returns 409 if the run is not startable. parameters: - $ref: "#/components/parameters/RunId" requestBody: required: false content: application/json: schema: $ref: "#/components/schemas/StartRunRequest" responses: "200": description: Run started content: application/json: schema: $ref: "#/components/schemas/RunStatusResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "409": description: Run is not in submitted status content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/pause: post: operationId: pauseRun tags: [Runs] summary: Pause Run description: Pauses a running run. Returns 409 if the run is not running. parameters: - $ref: "#/components/parameters/RunId" responses: "200": description: Run paused content: application/json: schema: $ref: "#/components/schemas/RunStatusResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "409": description: Run is not running content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/unpause: post: operationId: unpauseRun tags: [Runs] summary: Unpause Run description: Resumes a paused run. Returns 409 if the run is not paused. parameters: - $ref: "#/components/parameters/RunId" responses: "200": description: Run unpaused content: application/json: schema: $ref: "#/components/schemas/RunStatusResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "409": description: Run is not paused content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/archive: post: operationId: archiveRun tags: [Runs] summary: Archive Run description: > Marks a terminal run (`succeeded`, `failed`, or `dead`) as `archived`. Archived runs are hidden from default listings and are read-only until unarchived. Idempotent on already-archived runs. Returns 409 if the run is not terminal. parameters: - $ref: "#/components/parameters/RunId" responses: "200": description: Run archived (or already archived) content: application/json: schema: $ref: "#/components/schemas/RunStatusResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "409": description: Run is not terminal and cannot be archived content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/rewind: post: operationId: rewindRun tags: [Runs] summary: Rewind Run description: > Creates a new run from an earlier checkpoint of a terminal source run, archives the source run, and records `run.superseded_by` on the source after archive succeeds. Returns 207 when the new run was created but the source archive step failed. parameters: - $ref: "#/components/parameters/RunId" requestBody: required: false content: application/json: schema: $ref: "#/components/schemas/RewindRequest" responses: "200": description: Source archived and new run created content: application/json: schema: $ref: "#/components/schemas/RewindResponse" "207": description: New run created but source archive failed content: application/json: schema: $ref: "#/components/schemas/RewindResponse" "400": description: Invalid rewind target content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "409": description: Source run is archived or is not terminal content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "501": description: Server cannot access the run working directory content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/fork: post: operationId: forkRun tags: [Runs] summary: Fork Run description: > Creates a new run from a checkpoint of the source run. The source run is left untouched. parameters: - $ref: "#/components/parameters/RunId" requestBody: required: false content: application/json: schema: $ref: "#/components/schemas/ForkRequest" responses: "200": description: New run created content: application/json: schema: $ref: "#/components/schemas/ForkResponse" "400": description: Invalid fork target content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "409": description: Source run is archived content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "501": description: Server cannot access the run working directory content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/timeline: get: operationId: getRunTimeline tags: [Runs] summary: Get Run Timeline description: > Returns checkpoint timeline entries read from the run metadata branch. This endpoint does not rebuild missing metadata branches. parameters: - $ref: "#/components/parameters/RunId" responses: "200": description: Run checkpoint timeline content: application/json: schema: type: array items: $ref: "#/components/schemas/TimelineEntryResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "501": description: Server cannot access the run working directory content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/unarchive: post: operationId: unarchiveRun tags: [Runs] summary: Unarchive Run description: > Restores an archived run to its prior terminal status. Idempotent on runs that are terminal but not archived (returns the current status without emitting an event). Returns 409 if the run is active. parameters: - $ref: "#/components/parameters/RunId" responses: "200": description: Run unarchived (or already not archived) content: application/json: schema: $ref: "#/components/schemas/RunStatusResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "409": description: Run is active and cannot be unarchived content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/graph: get: operationId: retrieveRunGraph tags: [Runs] summary: Render SVG description: Renders the workflow graph as an SVG image using Graphviz. parameters: - $ref: "#/components/parameters/RunId" responses: "200": description: SVG image of the workflow graph content: image/svg+xml: schema: type: string "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/checkpoint: get: operationId: retrieveRunCheckpoint tags: [Run Internals] summary: Retrieve Run Checkpoint description: Returns the latest checkpoint data for a run, or null if no checkpoint has been recorded yet. parameters: - $ref: "#/components/parameters/RunId" responses: "200": description: Checkpoint data (null if not yet available) content: application/json: schema: oneOf: - $ref: "#/components/schemas/RunCheckpoint" - type: "null" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/boards/runs: get: operationId: listBoardRuns tags: [Runs] summary: List Board Runs description: Temporary board-view list of managed runs. This endpoint is UI-oriented and may change as the app evolves. parameters: - $ref: "#/components/parameters/PageLimit" - $ref: "#/components/parameters/PageOffset" responses: "200": description: Paginated list of runs for the board view content: application/json: schema: $ref: "#/components/schemas/PaginatedBoardRunList" /api/v1/runs/{id}/state: get: operationId: getRunState tags: [Run Internals] summary: Get Run State description: Returns the internal event-sourced run projection. This is not a stable public contract. parameters: - $ref: "#/components/parameters/RunId" responses: "200": description: Current run projection content: application/json: schema: $ref: "#/components/schemas/RunProjection" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/pull_request: post: operationId: createRunPullRequest tags: [Runs] summary: Create Run Pull Request description: Creates a pull request for a completed run on GitHub and persists the record on the server. parameters: - $ref: "#/components/parameters/RunId" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateRunPullRequestRequest" responses: "200": description: Pull request created content: application/json: schema: $ref: "#/components/schemas/PullRequestRecord" "400": description: Pull request creation does not apply to this run content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "409": description: >- Pull request already exists for this run. Clients can GET /runs/{id}/pull_request to retrieve the stored record. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "502": description: GitHub rejected the pull request creation request content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "503": description: GitHub integration is unavailable on the server content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" get: operationId: getRunPullRequest tags: [Runs] summary: Get Run Pull Request description: Returns the stored pull request record for a run plus live GitHub details. parameters: - $ref: "#/components/parameters/RunId" responses: "200": description: Pull request detail content: application/json: schema: $ref: "#/components/schemas/PullRequestDetail" "400": description: Pull request lookup does not apply to this run content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "404": description: Run or stored pull request record not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "502": description: Stored pull request record exists but GitHub could not find it content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "503": description: GitHub integration is unavailable on the server content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/pull_request/merge: post: operationId: mergeRunPullRequest tags: [Runs] summary: Merge Run Pull Request description: Merges the stored pull request for a run on GitHub. parameters: - $ref: "#/components/parameters/RunId" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/MergeRunPullRequestRequest" responses: "200": description: Pull request merged content: application/json: schema: $ref: "#/components/schemas/MergeRunPullRequestResponse" "400": description: Pull request merge does not apply to this run content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "404": description: Run or stored pull request record not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "502": description: GitHub rejected the merge request content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "503": description: GitHub integration is unavailable on the server content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/pull_request/close: post: operationId: closeRunPullRequest tags: [Runs] summary: Close Run Pull Request description: Closes the stored pull request for a run on GitHub. parameters: - $ref: "#/components/parameters/RunId" responses: "200": description: Pull request closed content: application/json: schema: $ref: "#/components/schemas/CloseRunPullRequestResponse" "400": description: Pull request close does not apply to this run content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "404": description: Run or stored pull request record not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "502": description: GitHub rejected the close request content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "503": description: GitHub integration is unavailable on the server content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/events: get: operationId: listRunEvents tags: [Run Internals] summary: List Run Events description: Returns a paginated JSON list of stored run events. parameters: - $ref: "#/components/parameters/RunId" - $ref: "#/components/parameters/SinceSeq" - $ref: "#/components/parameters/EventLimit" responses: "200": description: Paginated list of run events content: application/json: schema: $ref: "#/components/schemas/PaginatedEventList" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" post: operationId: appendRunEvent tags: [Run Internals] summary: Append Run Event description: Appends a validated event to the run event log. Intended for trusted internal callers. parameters: - $ref: "#/components/parameters/RunId" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/RunEvent" responses: "200": description: Event appended content: application/json: schema: $ref: "#/components/schemas/AppendEventResponse" "400": description: Invalid event payload content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/attach: get: operationId: attachRunEvents tags: [Run Internals] summary: Attach Run Events description: Opens an ordered server-sent event stream starting at `since_seq`, replaying persisted events and continuing with live updates while the run remains active. parameters: - $ref: "#/components/parameters/RunId" - $ref: "#/components/parameters/SinceSeq" responses: "200": description: Server-sent event stream content: text/event-stream: schema: type: string "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/blobs: post: operationId: writeRunBlob tags: [Run Internals] summary: Write Run Blob description: Writes an opaque binary blob and returns its content-addressed blob identifier. parameters: - $ref: "#/components/parameters/RunId" requestBody: required: true content: application/octet-stream: schema: type: string format: binary multipart/form-data: schema: type: object required: - manifest properties: manifest: $ref: "#/components/schemas/ArtifactBatchUploadManifest" additionalProperties: type: string format: binary description: | Strict multipart upload format. The `manifest` part must arrive first with JSON matching `ArtifactBatchUploadManifest`. Each subsequent file part name must match a manifest entry `part` value. encoding: manifest: contentType: application/json responses: "200": description: Blob written content: application/json: schema: $ref: "#/components/schemas/WriteBlobResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/blobs/{blobId}: get: operationId: readRunBlob tags: [Run Internals] summary: Read Run Blob description: Reads a previously stored blob by identifier. parameters: - $ref: "#/components/parameters/RunId" - $ref: "#/components/parameters/BlobId" responses: "200": description: Blob contents content: application/octet-stream: schema: type: string format: binary "404": description: Run or blob not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/questions: get: operationId: listRunQuestions tags: [Human-in-the-Loop] summary: List Run Questions description: Returns pending human-in-the-loop questions for a run. Questions are generated when the workflow needs user input to proceed. parameters: - $ref: "#/components/parameters/RunId" - $ref: "#/components/parameters/PageLimit" - $ref: "#/components/parameters/PageOffset" responses: "200": description: Array of pending questions content: application/json: schema: $ref: "#/components/schemas/PaginatedApiQuestionList" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/questions/{qid}/answer: post: operationId: submitRunAnswer tags: [Human-in-the-Loop] summary: Submit Run Answer description: Submits an answer to a pending question. The answer can be freeform text or a selected option key, depending on the question type. parameters: - $ref: "#/components/parameters/RunId" - $ref: "#/components/parameters/QuestionId" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/SubmitAnswerRequest" responses: "204": description: Answer accepted "400": description: Invalid option key content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "409": description: Question no longer exists or already answered content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/stages: get: operationId: listRunStages tags: [Run Internals] summary: List Run Stages description: Returns the ordered list of stages in a run's workflow graph with their current status and timing. Stages are bounded by the workflow graph size, typically fewer than 20. parameters: - $ref: "#/components/parameters/RunId" - $ref: "#/components/parameters/PageLimit" - $ref: "#/components/parameters/PageOffset" responses: "200": description: Array of run stages content: application/json: schema: $ref: "#/components/schemas/PaginatedRunStageList" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/stages/{stageId}/turns: get: operationId: listStageTurns tags: [Run Internals] summary: List Stage Turns description: Returns a paginated list of conversation turns within a specific stage, including system prompts, assistant responses, and tool invocations. parameters: - $ref: "#/components/parameters/RunId" - $ref: "#/components/parameters/StageId" - $ref: "#/components/parameters/PageLimit" - $ref: "#/components/parameters/PageOffset" responses: "200": description: Paginated list of conversation turns content: application/json: schema: $ref: "#/components/schemas/PaginatedStageTurnList" "404": description: Run or stage not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/artifacts: get: operationId: listRunArtifacts tags: [Run Internals] summary: List Run Artifacts description: Lists captured artifact files for a run. parameters: - $ref: "#/components/parameters/RunId" responses: "200": description: Artifact files captured for the run content: application/json: schema: $ref: "#/components/schemas/RunArtifactListResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/files: get: operationId: listRunFiles tags: [Run Outputs] summary: List Run Files Changed description: | Returns the set of file changes produced by a run as a list of before/after diffs. While the run's sandbox is reachable, diffs are resolved live against the sandbox working tree at the current HEAD. Once the sandbox is gone, the response may degrade to the unified-patch string captured at run end (see `meta.degraded` and `meta.patch`). Responses are bounded by per-file (256 KiB / 20k lines), per-run aggregate (5 MiB), and per-request (200 files) caps. Files exceeding a cap are returned with `truncated: true` and empty `contents`. Sensitive paths (credentials, keys) are elided with `sensitive: true` and empty `contents`. parameters: - $ref: "#/components/parameters/RunId" - $ref: "#/components/parameters/PageLimit" - $ref: "#/components/parameters/PageOffset" - name: from_sha in: query required: false description: Reserved for future use. Only the default value is accepted in the current API version; any other value returns 400. schema: type: string pattern: "^[0-9a-f]{7,40}$" - name: to_sha in: query required: false description: Reserved for future use. Only the default value is accepted in the current API version; any other value returns 400. schema: type: string pattern: "^[0-9a-f]{7,40}$" responses: "200": description: File diffs for the run content: application/json: schema: $ref: "#/components/schemas/PaginatedRunFileList" "400": description: Malformed query parameter (invalid SHA format, or non-default value for `from_sha`/`to_sha`). content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "404": description: Run not found (or caller lacks access; returned as 404 to prevent enumeration). content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "503": description: Transient sandbox subprocess failure (timeout, process kill). Safe to retry. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/stages/{stageId}/artifacts: get: operationId: listStageArtifacts tags: [Run Internals] summary: List Stage Artifacts description: Lists artifact filenames stored for a stage. parameters: - $ref: "#/components/parameters/RunId" - $ref: "#/components/parameters/StageId" responses: "200": description: Artifact filenames for the stage content: application/json: schema: $ref: "#/components/schemas/ArtifactListResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" post: operationId: putStageArtifact tags: [Run Internals] summary: Put Stage Artifact description: | Uploads one or more artifacts for a stage. Intended for trusted internal callers. The server accepts both: - `application/octet-stream` for single-file uploads with the `filename` query parameter - strict manifest-first `multipart/form-data` uploads documented by `ArtifactBatchUploadManifest` The generated Rust client currently exposes the octet-stream variant because the OpenAPI code generator in this repo does not support multiple request media types on one operation. parameters: - $ref: "#/components/parameters/RunId" - $ref: "#/components/parameters/StageId" - name: filename in: query required: false description: Relative artifact path for `application/octet-stream` uploads. Ignored for multipart uploads. schema: type: string requestBody: required: true content: application/octet-stream: schema: type: string format: binary responses: "204": description: Artifact written "400": description: Invalid filename, multipart manifest, checksum, or upload body content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/stages/{stageId}/artifacts/download: get: operationId: getStageArtifact tags: [Run Internals] summary: Get Stage Artifact description: Downloads an artifact by filename. parameters: - $ref: "#/components/parameters/RunId" - $ref: "#/components/parameters/StageId" - $ref: "#/components/parameters/ArtifactFilename" responses: "200": description: Artifact contents content: application/octet-stream: schema: type: string format: binary "400": description: Missing filename content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "404": description: Run, stage, or artifact not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/billing: get: operationId: retrieveRunBilling tags: [Run Outputs] summary: Retrieve Run Billing description: Returns token counts and billed totals broken down by stage and model for a specific run. parameters: - $ref: "#/components/parameters/RunId" responses: "200": description: Billing data content: application/json: schema: $ref: "#/components/schemas/RunBilling" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/settings: get: operationId: retrieveRunSettings tags: [Run Internals] summary: Retrieve Run Settings description: Returns the persisted dense `WorkflowSettings` snapshot used to launch this run. parameters: - $ref: "#/components/parameters/RunId" responses: "200": description: Run settings content: application/json: schema: $ref: "#/components/schemas/WorkflowSettings" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/preview: post: operationId: generatePreviewUrl tags: [Human-in-the-Loop] summary: Preview URL description: Generates a preview URL for a port exposed by the run's sandbox environment. parameters: - $ref: "#/components/parameters/RunId" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/PreviewUrlRequest" responses: "201": description: Preview URL created content: application/json: schema: $ref: "#/components/schemas/PreviewUrlResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "409": description: Run has no active sandbox content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/ssh: post: operationId: createRunSshAccess tags: [Human-in-the-Loop] summary: SSH Access description: Creates a time-limited SSH command for the run's sandbox environment. parameters: - $ref: "#/components/parameters/RunId" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/SshAccessRequest" responses: "201": description: SSH command created content: application/json: schema: $ref: "#/components/schemas/SshAccessResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "409": description: Run has no active sandbox or provider does not support SSH content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/sandbox/files: get: operationId: listSandboxFiles tags: [Human-in-the-Loop] summary: List Sandbox Files description: Lists directory entries from the run's sandbox environment. parameters: - $ref: "#/components/parameters/RunId" - in: query name: path required: true schema: type: string - in: query name: depth required: false schema: type: integer minimum: 1 responses: "200": description: Directory entries content: application/json: schema: $ref: "#/components/schemas/SandboxFileListResponse" "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "409": description: Run has no active sandbox content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/runs/{id}/sandbox/file: get: operationId: getSandboxFile tags: [Human-in-the-Loop] summary: Download Sandbox File description: Downloads a file from the run's sandbox environment. parameters: - $ref: "#/components/parameters/RunId" - in: query name: path required: true schema: type: string responses: "200": description: File contents content: application/octet-stream: schema: type: string format: binary "404": description: Run or file not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "409": description: Run has no active sandbox content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" put: operationId: putSandboxFile tags: [Human-in-the-Loop] summary: Upload Sandbox File description: Uploads a file into the run's sandbox environment. parameters: - $ref: "#/components/parameters/RunId" - in: query name: path required: true schema: type: string requestBody: required: true content: application/octet-stream: schema: type: string format: binary responses: "204": description: File written "404": description: Run not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "409": description: Run has no active sandbox content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" # ── Insights ────────────────────────────────────────────────────────── /api/v1/insights/queries: get: operationId: listSavedQueries tags: [Insights] summary: List Saved Queries description: Returns a paginated list of saved SQL queries for the insights editor. parameters: - $ref: "#/components/parameters/PageLimit" - $ref: "#/components/parameters/PageOffset" responses: "200": description: Paginated list of saved queries content: application/json: schema: $ref: "#/components/schemas/PaginatedSavedQueryList" post: operationId: createSavedQuery tags: [Insights] summary: Create Saved Query description: Saves a new named SQL query for later reuse. requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/SaveQueryRequest" responses: "201": description: Query saved content: application/json: schema: $ref: "#/components/schemas/SavedQuery" /api/v1/insights/queries/{id}: get: operationId: retrieveSavedQuery tags: [Insights] summary: Retrieve Saved Query description: Returns a single saved query by ID. parameters: - $ref: "#/components/parameters/InsightQueryId" responses: "200": description: Saved query content: application/json: schema: $ref: "#/components/schemas/SavedQuery" "404": description: Query not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" put: operationId: updateSavedQuery tags: [Insights] summary: Update Saved Query description: Replaces the name and SQL of an existing saved query. parameters: - $ref: "#/components/parameters/InsightQueryId" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/SaveQueryRequest" responses: "200": description: Query updated content: application/json: schema: $ref: "#/components/schemas/SavedQuery" "404": description: Query not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" delete: operationId: deleteSavedQuery tags: [Insights] summary: Delete Saved Query description: Permanently removes a saved query. parameters: - $ref: "#/components/parameters/InsightQueryId" responses: "204": description: Query deleted "404": description: Query not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/insights/execute: post: operationId: executeQuery tags: [Insights] summary: Execute Query description: Executes an ad-hoc SQL query against the analytics database and returns columnar results. requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ExecuteQueryRequest" responses: "200": description: Query results content: application/json: schema: $ref: "#/components/schemas/ExecuteQueryResponse" "400": description: Bad SQL or query error content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/insights/history: get: operationId: listQueryHistory tags: [Insights] summary: List Query History description: Returns a paginated history of recently executed queries with timing and row counts. parameters: - $ref: "#/components/parameters/PageLimit" - $ref: "#/components/parameters/PageOffset" responses: "200": description: Paginated list of history entries content: application/json: schema: $ref: "#/components/schemas/PaginatedHistoryEntryList" # ── Billing ────────────────────────────────────────────────────────── /api/v1/billing: get: operationId: getAggregateBilling tags: [Billing] summary: Aggregate Billing description: Returns aggregate token counts and billed totals across all completed runs since server start. responses: "200": description: Aggregate billing data content: application/json: schema: $ref: "#/components/schemas/AggregateBilling" # ── System ─────────────────────────────────────────────────────────── /api/v1/attach: get: operationId: attachEvents tags: [System] summary: Attach Global Events description: Opens a server-sent event stream for live run events across the server. parameters: - name: run_id in: query required: false description: Optional comma-separated list of run IDs to include. schema: type: string responses: "200": description: Server-sent event stream content: text/event-stream: schema: type: string /api/v1/system/info: get: operationId: getSystemInfo tags: [System] summary: Retrieve System Info description: Returns runtime details about the active Fabro server process. responses: "200": description: System information content: application/json: schema: $ref: "#/components/schemas/SystemInfoResponse" /api/v1/system/df: get: operationId: getSystemDiskUsage tags: [System] summary: Retrieve System Disk Usage description: Returns disk usage for the server storage directory. parameters: - name: verbose in: query required: false description: Include per-run disk usage rows. schema: type: boolean default: false responses: "200": description: Disk usage summary content: application/json: schema: $ref: "#/components/schemas/DiskUsageResponse" /api/v1/system/prune/runs: post: operationId: pruneRuns tags: [System] summary: Prune Runs description: Deletes completed runs matching the provided filters, or previews the deletion set when dry-run is enabled. requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/PruneRunsRequest" responses: "200": description: Prune result content: application/json: schema: $ref: "#/components/schemas/PruneRunsResponse" "400": description: Invalid prune request content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" # ── Secrets ────────────────────────────────────────────────────────── /api/v1/secrets: get: operationId: listSecrets tags: [Secrets] summary: List vault secrets description: Returns workflow-visible vault secret names and timestamps. Secret values are never exposed. responses: "200": description: Secret metadata list content: application/json: schema: $ref: "#/components/schemas/SecretListResponse" post: operationId: createSecret tags: [Secrets] summary: Store or update a vault secret description: Stores a secret in the workflow-visible vault. Anything stored here may be used by workflows. requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateSecretRequest" responses: "200": description: Secret stored content: application/json: schema: $ref: "#/components/schemas/SecretMetadata" "400": description: Invalid secret name or request body content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" delete: operationId: deleteSecretByName tags: [Secrets] summary: Delete a vault secret requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/DeleteSecretRequest" responses: "204": description: Secret deleted "400": description: Invalid secret name or request body content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "404": description: Secret not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "500": description: Secret store write failed content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" # ── Repos ──────────────────────────────────────────────────────────── /api/v1/repos/github/{owner}/{name}: get: operationId: getGithubRepo tags: [Repos] summary: Check server access to a GitHub repository parameters: - name: owner in: path required: true schema: type: string - name: name in: path required: true schema: type: string responses: "200": description: Repository access details content: application/json: schema: $ref: "#/components/schemas/RepoCheckResponse" # ── Models ─────────────────────────────────────────────────────────── /api/v1/models: get: operationId: listModels tags: [Models] summary: List Models description: Returns a paginated list of available LLM models from the built-in catalog. parameters: - $ref: "#/components/parameters/ModelProviderFilter" - $ref: "#/components/parameters/ModelQueryFilter" - $ref: "#/components/parameters/PageLimit" - $ref: "#/components/parameters/PageOffset" responses: "200": description: Paginated list of models content: application/json: schema: $ref: "#/components/schemas/PaginatedModelList" "400": description: Invalid filter value content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/models/{id}/test: post: operationId: testModel tags: [Models] summary: Test Model description: Tests a model by sending a simple prompt and reporting pass/fail. parameters: - name: id in: path required: true schema: type: string description: The model identifier. - $ref: "#/components/parameters/ModelTestModeParam" responses: "200": description: Test result content: application/json: schema: $ref: "#/components/schemas/ModelTestResult" "400": description: Invalid test mode content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "404": description: Model not found content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" # ── Completions ─────────────────────────────────────────────────────── /api/v1/completions: post: operationId: createCompletion tags: [Completions] summary: Create Completion description: | Generate a text completion. Set `stream: true` for SSE streaming. All SSE frames use `event: stream_event` with a JSON-serialized StreamEvent payload. StreamEvent types: stream_start, text_start, text_delta, text_end, tool_call_start, tool_call_delta, tool_call_end, finish, error. requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateCompletionRequest" responses: "200": description: Completion result (JSON when stream=false, SSE when stream=true) content: application/json: schema: $ref: "#/components/schemas/CompletionResponse" "400": description: Invalid request content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" # ── Settings ────────────────────────────────────────────────────────── /api/v1/settings: get: operationId: retrieveServerSettings tags: [Settings] summary: Retrieve Server Settings description: > Returns the server's current in-memory settings view as the typed `ServerSettings` payload. responses: "200": description: Server settings content: application/json: schema: $ref: "#/components/schemas/ServerSettings" components: securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: opaque description: > Raw dev token passed as `Authorization: Bearer fabro_dev_...` when `server.auth.methods` includes `dev-token`. SessionCookie: type: apiKey in: cookie name: __fabro_session description: > Private session cookie issued after a successful web login. The server verifies and decodes the cookie before authenticating the request. parameters: RunId: name: id in: path required: true description: Unique run identifier (ULID). schema: type: string example: 01JNQVR7M0EJ5GKAT2SC4ERS1Z RunSelector: name: selector in: query required: true description: Run selector, such as a run ID prefix, workflow slug, or workflow name. schema: type: string example: nightly-build StageId: name: stageId in: path required: true description: Identifier of a stage within a run's workflow graph, serialized as `node_id@visit`. schema: type: string example: code@2 BlobId: name: blobId in: path required: true description: Content-addressed blob identifier. schema: type: string pattern: '^[0-9a-f]{64}$' example: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 ArtifactFilename: name: filename in: query required: true description: Relative artifact path. `/` is allowed as a path separator. Backslash, empty segments, and traversal segments (`.` and `..`) are invalid. schema: type: string example: src/lib.rs SinceSeq: name: since_seq in: query required: false description: First event sequence number to include. schema: type: integer minimum: 1 default: 1 example: 42 EventLimit: name: limit in: query required: false description: Maximum number of events to return. schema: type: integer minimum: 1 maximum: 1000 default: 100 example: 100 QuestionId: name: qid in: path required: true description: Unique identifier of a pending question. schema: type: string example: q-001 InsightQueryId: name: id in: path required: true description: Unique identifier of a saved query. schema: type: string example: "1" CheckpointFilter: name: checkpoint in: query required: false description: Filter to a specific checkpoint ID. Omit to include all changes. schema: type: string example: cp-3 PageLimit: name: page[limit] in: query required: false description: Maximum number of items to return per page. schema: type: integer minimum: 1 maximum: 100 default: 20 example: 20 PageOffset: name: page[offset] in: query required: false description: Number of items to skip before returning results. schema: type: integer minimum: 0 default: 0 example: 0 IncludeArchived: name: include_archived in: query required: false description: Whether to include archived runs in the response. Defaults to `false`. schema: type: boolean default: false example: false ForceRunDelete: name: force in: query required: false description: Whether to force deletion of an active run. Defaults to `false`. schema: type: boolean default: false example: false ModelProviderFilter: name: provider in: query required: false description: Filter models by provider name. Invalid values return `400`. schema: type: string example: anthropic ModelQueryFilter: name: query in: query required: false description: Case-insensitive substring search across `id`, `display_name`, and `aliases`. schema: type: string example: opus ModelTestModeParam: name: mode in: query required: false description: Test mode for the single-model test endpoint. Defaults to `basic`. schema: $ref: "#/components/schemas/ModelTestMode" example: basic schemas: InstallSessionResponse: description: Current browser-install session snapshot with secrets redacted. type: object required: - completed_steps - prefill properties: completed_steps: type: array items: type: string llm: oneOf: - $ref: "#/components/schemas/InstallLlmSummary" - type: "null" server: oneOf: - $ref: "#/components/schemas/InstallServerConfigInput" - type: "null" object_store: oneOf: - $ref: "#/components/schemas/InstallObjectStoreSummary" - type: "null" github: oneOf: - $ref: "#/components/schemas/InstallGithubSummary" - type: "null" prefill: $ref: "#/components/schemas/InstallPrefill" InstallPrefill: description: Server-detected defaults used to prefill the browser install wizard. type: object required: - canonical_url - object_store_local_root properties: canonical_url: type: string format: uri object_store_local_root: type: string InstallLlmValidationResponse: description: Successful response from install-time LLM credential validation. type: object required: - ok properties: ok: type: boolean example: true InstallLlmTestInput: description: Input for install-time LLM credential validation. Supported providers in install v1 are `anthropic`, `openai`, and `gemini`. type: object required: - provider - api_key properties: provider: type: string example: anthropic api_key: type: string InstallLlmProvidersInput: description: LLM providers selected during browser install. type: object required: - providers properties: providers: type: array minItems: 1 items: $ref: "#/components/schemas/InstallLlmProviderInput" InstallLlmProviderInput: description: One persisted LLM provider configuration collected during browser install. Supported providers in install v1 are `anthropic`, `openai`, and `gemini`. type: object required: - provider - api_key properties: provider: type: string example: anthropic api_key: type: string InstallLlmSummary: description: Redacted summary of persisted LLM install choices. type: object properties: providers: type: array items: type: object required: - provider - configured properties: provider: type: string configured: type: boolean InstallServerConfigInput: description: Canonical server URL confirmed during browser install. type: object required: - canonical_url properties: canonical_url: type: string format: uri InstallObjectStoreValidationResponse: description: Successful response from install-time object-store validation. type: object required: - ok properties: ok: type: boolean example: true InstallObjectStoreInput: description: Object-store mode selected during browser install. type: object required: - provider properties: provider: type: string enum: [local, s3] root: type: string bucket: type: string region: type: string credential_mode: type: string enum: [runtime, access_key] access_key_id: type: string secret_access_key: type: string InstallObjectStoreSummary: description: Redacted summary of the object-store mode selected during browser install. type: object required: - provider properties: provider: type: string enum: [local, s3] root: type: string bucket: type: string region: type: string credential_mode: type: string enum: [runtime, access_key] manual_credentials_saved: type: boolean InstallGithubTokenTestInput: description: Input for install-time GitHub token validation. type: object required: - token properties: token: type: string InstallGithubTokenTestResponse: description: Successful response from install-time GitHub token validation. type: object required: - username properties: username: type: string InstallGithubTokenInput: description: GitHub personal access token chosen during browser install. type: object required: - token - username properties: token: type: string username: type: string InstallGithubAppManifestInput: description: Input required to build the browser-install GitHub App manifest. type: object required: - owner - app_name - allowed_username properties: owner: $ref: "#/components/schemas/InstallGithubAppOwner" app_name: type: string allowed_username: type: string InstallGithubAppOwner: description: Owner of the GitHub App being created during browser install. type: object required: - kind properties: kind: type: string enum: [personal, org] slug: type: string description: Required when `kind` is `org`; the organization slug. InstallGithubAppManifestResponse: description: Browser handoff payload for the GitHub App creation flow. type: object required: - manifest - github_form_action - state properties: manifest: type: object additionalProperties: true github_form_action: type: string format: uri state: description: | CSRF token the browser must echo back to GitHub as a hidden `state` form field alongside `manifest`. GitHub preserves it on the redirect to `redirect_url` so the server can match the callback to this pending install. type: string InstallGithubSummary: description: Redacted summary of the GitHub install strategy selected during browser install. type: object required: - strategy properties: strategy: type: string enum: [token, app] username: type: string owner: $ref: "#/components/schemas/InstallGithubAppOwner" app_name: type: string slug: type: string allowed_username: type: string InstallFinishResponse: description: Response returned after install outputs are persisted successfully. type: object required: - status - restart_url properties: status: type: string enum: [completing] restart_url: type: string format: uri dev_token: type: string description: | Dev token used to bootstrap login. Only included when the operator chose the personal access token flow; GitHub App installs rely on OAuth and do not receive a dev token. # ── Pagination ─────────────────────────────────────────────────────── PaginationMeta: description: Pagination metadata included in every paginated response. type: object required: - has_more properties: has_more: type: boolean description: Whether additional pages of results are available. example: true PaginatedRunList: description: Paginated list of runs. type: object required: - data - meta properties: data: type: array items: $ref: "#/components/schemas/StoreRunSummary" meta: $ref: "#/components/schemas/PaginationMeta" PaginatedBoardRunList: description: Paginated list of board runs with shared canonical fields plus board metadata. type: object required: - columns - data - meta properties: columns: type: array items: $ref: "#/components/schemas/BoardColumnDefinition" data: type: array items: $ref: "#/components/schemas/RunListItem" meta: $ref: "#/components/schemas/PaginationMeta" PaginatedModelList: description: Paginated list of models. type: object required: - data - meta properties: data: type: array items: $ref: "#/components/schemas/Model" meta: $ref: "#/components/schemas/PaginationMeta" ModelLimits: description: Token limits for a model. type: object required: - context_window properties: context_window: type: integer format: int64 description: Maximum context window size in tokens. example: 1000000 max_output: type: ["integer", "null"] format: int64 description: Maximum output tokens, if known. example: 128000 ModelFeatures: description: Capability flags for a model. type: object required: - tools - vision - reasoning properties: tools: type: boolean description: Whether the model supports tool use. vision: type: boolean description: Whether the model supports vision/image inputs. reasoning: type: boolean description: Whether the model supports extended reasoning. ModelCosts: description: Pricing per million tokens in USD. type: object properties: input_cost_per_mtok: type: ["number", "null"] format: double description: Cost per million input tokens in USD. example: 15.0 output_cost_per_mtok: type: ["number", "null"] format: double description: Cost per million output tokens in USD. example: 75.0 cache_input_cost_per_mtok: type: ["number", "null"] format: double description: Cost per million cached input tokens in USD. example: 1.50 Model: description: An available LLM model from the built-in catalog. type: object required: - id - provider - family - display_name - limits - features - costs - aliases - default properties: id: type: string description: Unique model identifier. example: "claude-opus-4-6" provider: type: string description: Provider that serves this model. example: "anthropic" family: type: string description: Model family grouping. example: "claude-4" display_name: type: string description: Human-readable model name. example: "Claude Opus 4.6" limits: $ref: "#/components/schemas/ModelLimits" training: type: ["string", "null"] description: Training data cutoff date (YYYY-MM-DD). example: "2025-08-01" features: $ref: "#/components/schemas/ModelFeatures" costs: $ref: "#/components/schemas/ModelCosts" estimated_output_tps: type: ["number", "null"] format: double description: Estimated output tokens per second. aliases: type: array items: type: string description: Alternative names that resolve to this model. example: ["opus"] default: type: boolean description: Whether this is the default model for its provider. ModelTestResult: description: Result of testing a model in `basic` or `deep` mode. type: object required: - model_id - status properties: model_id: type: string description: The model identifier that was tested. example: "claude-opus-4-6" status: type: string enum: - ok - error - skip description: Whether the model responded successfully, failed, or was skipped because its provider is not configured. error_message: type: ["string", "null"] description: Error details when status is "error". ModelTestMode: description: Single-model test mode. type: string enum: - basic - deep # ── Completion Schemas ───────────────────────────────────────────── CompletionMessage: description: A message in the conversation. type: object required: [role, content] properties: role: type: string enum: [system, user, assistant, tool, developer] description: The role of the message author. content: type: array description: Content parts of the message. items: $ref: "#/components/schemas/CompletionContentPart" name: type: string description: Optional name for the message author. tool_call_id: type: string description: Tool call ID for tool result messages. CompletionContentPart: description: A content part within a message, discriminated by `kind`. type: object required: [kind] properties: kind: type: string description: "Content part type: text, image, tool_call, tool_result, thinking, etc." data: description: Content data, structure depends on kind. CompletionToolDefinition: description: A tool available for the model to call. type: object required: [name, description, parameters] properties: name: type: string description: Tool name. description: type: string description: Human-readable tool description. parameters: description: JSON Schema for the tool's parameters. CompletionToolChoice: description: Controls how the model selects tools. type: object required: [mode] properties: mode: type: string enum: [auto, none, required, named] description: Tool selection mode. tool_name: type: string description: Required when mode is "named". CreateCompletionRequest: type: object required: [messages] properties: messages: type: array description: The conversation messages. items: $ref: "#/components/schemas/CompletionMessage" model: type: string description: Model ID or alias. Server picks default if omitted. system: type: string description: System prompt (convenience; prepended as a system message). stream: type: boolean default: true description: Stream response via SSE. tools: type: array description: Tool definitions available to the model. items: $ref: "#/components/schemas/CompletionToolDefinition" tool_choice: $ref: "#/components/schemas/CompletionToolChoice" schema: description: JSON Schema for structured output. temperature: type: number format: double max_tokens: type: integer format: int64 top_p: type: number format: double stop_sequences: type: array items: type: string description: Stop sequences. reasoning_effort: type: string description: Reasoning effort level. provider: type: string description: Provider to route to. provider_options: description: Provider-specific options. CompletionUsage: type: object required: [input_tokens, output_tokens] properties: input_tokens: type: integer format: int64 output_tokens: type: integer format: int64 CompletionResponse: type: object required: [id, model, message, stop_reason, usage] properties: id: type: string model: type: string message: $ref: "#/components/schemas/CompletionMessage" stop_reason: type: string description: Why generation stopped (end_turn, max_tokens, tool_calls). usage: $ref: "#/components/schemas/CompletionUsage" output: description: Parsed structured output when schema was provided. PaginatedSavedQueryList: description: Paginated list of saved queries. type: object required: - data - meta properties: data: type: array items: $ref: "#/components/schemas/SavedQuery" meta: $ref: "#/components/schemas/PaginationMeta" PaginatedHistoryEntryList: description: Paginated list of query history entries. type: object required: - data - meta properties: data: type: array items: $ref: "#/components/schemas/HistoryEntry" meta: $ref: "#/components/schemas/PaginationMeta" PaginatedStageTurnList: description: Paginated list of stage turns. type: object required: - data - meta properties: data: type: array items: $ref: "#/components/schemas/StageTurn" meta: $ref: "#/components/schemas/PaginationMeta" PaginatedApiQuestionList: description: Paginated list of pending questions. type: object required: - data - meta properties: data: type: array items: $ref: "#/components/schemas/ApiQuestion" meta: $ref: "#/components/schemas/PaginationMeta" PaginatedRunStageList: description: Paginated list of run stages. type: object required: - data - meta properties: data: type: array items: $ref: "#/components/schemas/RunStage" meta: $ref: "#/components/schemas/PaginationMeta" # ── Run Schemas ────────────────────────────────────────────────────── RunStatus: description: > Lifecycle status of a run. `archived` is a terminal status reached by an explicit user action on a previously terminal (`succeeded`, `failed`, or `dead`) run; archived runs are hidden from default listings and are read-only until unarchived. oneOf: - $ref: "#/components/schemas/RunStatusSubmitted" - $ref: "#/components/schemas/RunStatusQueued" - $ref: "#/components/schemas/RunStatusStarting" - $ref: "#/components/schemas/RunStatusRunning" - $ref: "#/components/schemas/RunStatusBlocked" - $ref: "#/components/schemas/RunStatusPaused" - $ref: "#/components/schemas/RunStatusRemoving" - $ref: "#/components/schemas/RunStatusSucceeded" - $ref: "#/components/schemas/RunStatusFailed" - $ref: "#/components/schemas/RunStatusDead" - $ref: "#/components/schemas/RunStatusArchived" discriminator: propertyName: kind mapping: submitted: "#/components/schemas/RunStatusSubmitted" queued: "#/components/schemas/RunStatusQueued" starting: "#/components/schemas/RunStatusStarting" running: "#/components/schemas/RunStatusRunning" blocked: "#/components/schemas/RunStatusBlocked" paused: "#/components/schemas/RunStatusPaused" removing: "#/components/schemas/RunStatusRemoving" succeeded: "#/components/schemas/RunStatusSucceeded" failed: "#/components/schemas/RunStatusFailed" dead: "#/components/schemas/RunStatusDead" archived: "#/components/schemas/RunStatusArchived" RunStatusSubmitted: type: object required: - kind properties: kind: type: string enum: - submitted RunStatusQueued: type: object required: - kind properties: kind: type: string enum: - queued RunStatusStarting: type: object required: - kind properties: kind: type: string enum: - starting RunStatusRunning: type: object required: - kind properties: kind: type: string enum: - running RunStatusBlocked: type: object required: - kind - blocked_reason properties: kind: type: string enum: - blocked blocked_reason: $ref: "#/components/schemas/BlockedReason" RunStatusPaused: type: object required: - kind - prior_block properties: kind: type: string enum: - paused prior_block: oneOf: - $ref: "#/components/schemas/BlockedReason" - type: "null" RunStatusRemoving: type: object required: - kind properties: kind: type: string enum: - removing RunStatusSucceeded: type: object required: - kind - reason properties: kind: type: string enum: - succeeded reason: $ref: "#/components/schemas/SuccessReason" RunStatusFailed: type: object required: - kind - reason properties: kind: type: string enum: - failed reason: $ref: "#/components/schemas/FailureReason" RunStatusDead: type: object required: - kind properties: kind: type: string enum: - dead RunStatusArchived: type: object required: - kind - prior properties: kind: type: string enum: - archived prior: $ref: "#/components/schemas/TerminalStatus" TerminalStatus: description: Terminal run status captured inside an archived run. oneOf: - $ref: "#/components/schemas/RunStatusSucceeded" - $ref: "#/components/schemas/RunStatusFailed" - $ref: "#/components/schemas/RunStatusDead" discriminator: propertyName: kind mapping: succeeded: "#/components/schemas/RunStatusSucceeded" failed: "#/components/schemas/RunStatusFailed" dead: "#/components/schemas/RunStatusDead" SuccessReason: description: Reason attached to a successful terminal run status. type: string enum: - completed - partial_success FailureReason: description: Reason attached to a failed terminal run status. type: string enum: - workflow_error - cancelled - terminated - transient_infra - budget_exhausted - launch_failed - bootstrap_failed - sandbox_init_failed RunManifest: description: Self-contained workflow run manifest. type: object required: - version - cwd - target - workflows properties: version: type: integer description: Manifest schema version. example: 1 run_id: type: ["string", "null"] description: Optional pre-generated run ID to use instead of allocating a new ULID. example: "01HV6D7S5YF4Z4B2M7K4N0Q6T9" cwd: type: string description: CLI working directory at invocation time. example: "/tmp/project" git: $ref: "#/components/schemas/ManifestGit" goal: $ref: "#/components/schemas/ManifestGoal" args: $ref: "#/components/schemas/ManifestArgs" target: $ref: "#/components/schemas/ManifestTarget" configs: type: array items: $ref: "#/components/schemas/ManifestConfig" workflows: type: object additionalProperties: $ref: "#/components/schemas/ManifestWorkflow" ManifestGit: description: Observable git state from the CLI working directory. type: object required: - origin_url - branch - sha - clean properties: origin_url: type: string description: Remote origin URL with any embedded credentials removed. example: "https://github.com/acme/my-app.git" branch: type: string description: Current branch name. example: feature/foo sha: type: string description: Current commit SHA. example: abc123def clean: type: boolean description: Whether the working tree has uncommitted changes. ManifestGoal: description: Resolved goal with provenance. type: object required: - type - text properties: type: type: string enum: - value - file - graph text: type: string description: Resolved goal content. path: type: ["string", "null"] description: Original goal file path when the goal came from a file. ManifestArgs: description: Sparse command-local args that affect run settings. type: object properties: model: type: string provider: type: string sandbox: type: string verbose: type: boolean dry_run: type: boolean auto_approve: type: boolean no_retro: type: boolean preserve_sandbox: type: boolean label: type: array items: type: string ManifestTarget: type: object required: - identifier - path properties: identifier: type: string description: What the user typed. example: smoke path: type: string description: Resolved path that keys into the workflows map. example: .fabro/workflows/smoke/workflow.fabro ManifestConfig: type: object required: - type properties: type: type: string enum: - project - user path: type: ["string", "null"] source: type: ["string", "null"] ManifestWorkflowConfig: type: object required: - path - source properties: path: type: string source: type: string ManifestFileEntry: description: A bundled file with discovery metadata. type: object required: - content - ref properties: content: type: string ref: $ref: "#/components/schemas/ManifestFileRef" ManifestFileRef: type: object required: - type - original properties: type: type: string enum: - file_inline - import - dockerfile original: type: string from: type: ["string", "null"] ManifestWorkflow: type: object required: - source properties: source: type: string config: $ref: "#/components/schemas/ManifestWorkflowConfig" files: type: object additionalProperties: $ref: "#/components/schemas/ManifestFileEntry" PreflightResponse: type: object required: - ok - workflow - checks properties: ok: type: boolean description: Whether preflight passed using the CLI-compatible success rule. workflow: $ref: "#/components/schemas/PreflightWorkflowSummary" checks: $ref: "#/components/schemas/PreflightCheckReport" RenderWorkflowGraphRequest: type: object required: - manifest properties: manifest: $ref: "#/components/schemas/RunManifest" format: $ref: "#/components/schemas/RenderWorkflowGraphFormat" direction: $ref: "#/components/schemas/RenderWorkflowGraphDirection" RenderWorkflowGraphFormat: type: string enum: - svg RenderWorkflowGraphDirection: type: string enum: - lr - tb PreflightWorkflowSummary: type: object required: - name - nodes - edges - goal - diagnostics properties: name: type: string graph_path: type: ["string", "null"] nodes: type: integer edges: type: integer goal: type: string diagnostics: type: array items: $ref: "#/components/schemas/WorkflowDiagnostic" WorkflowDiagnostic: type: object required: - rule - severity - message properties: rule: type: string severity: type: string enum: - error - warning - info message: type: string node_id: type: ["string", "null"] edge: type: ["array", "null"] minItems: 2 maxItems: 2 items: type: string fix: type: ["string", "null"] PreflightCheckReport: type: object required: - title - sections properties: title: type: string sections: type: array items: $ref: "#/components/schemas/PreflightCheckSection" PreflightCheckSection: type: object required: - title - checks properties: title: type: string checks: type: array items: $ref: "#/components/schemas/PreflightCheckResult" PreflightCheckResult: type: object required: - name - status - summary - details properties: name: type: string status: type: string enum: - pass - warning - error summary: type: string details: type: array items: $ref: "#/components/schemas/PreflightCheckDetail" remediation: type: ["string", "null"] PreflightCheckDetail: type: object required: - text - warn properties: text: type: string warn: type: boolean StartRunRequest: description: Request body for starting or resuming a run. type: object properties: resume: type: boolean description: Resume from checkpoint instead of starting from submitted state. default: false RunStatusResponse: description: Current status of a run with optional error and queue position. type: object required: - id - status - created_at properties: id: type: string description: Unique run identifier (ULID). example: 01JNQVR7M0EJ5GKAT2SC4ERS1Z status: $ref: "#/components/schemas/RunStatus" error: $ref: "#/components/schemas/RunError" queue_position: type: integer description: Position in the queue (1-based). Only present when the status kind is `queued`. example: 3 pending_control: oneOf: - $ref: "#/components/schemas/RunControlAction" - type: "null" created_at: type: string format: date-time description: Timestamp when the run was created. example: "2026-03-06T14:30:00Z" ApiQuestionOption: description: A selectable option for a multiple-choice or multi-select question. type: object required: - key - label properties: key: type: string description: Machine-readable option key used when submitting an answer. example: option_a label: type: string description: Human-readable label displayed to the user. example: Accept changes ApiQuestion: description: A pending human-in-the-loop question generated by a workflow stage. type: object required: - id - text - stage - question_type - options - allow_freeform properties: id: type: string description: Unique question identifier. example: q-001 text: type: string description: The question text displayed to the user. example: Should we proceed with the proposed changes? stage: type: string description: Workflow stage identifier that produced the question. example: gate question_type: $ref: "#/components/schemas/QuestionType" options: type: array description: Available options for selection-based questions. Empty for freeform questions. items: $ref: "#/components/schemas/ApiQuestionOption" allow_freeform: type: boolean description: Whether the user may provide freeform text in addition to selecting options. example: true timeout_seconds: type: ["number", "null"] format: double description: Timeout for the question when configured by the workflow. example: 30 context_display: type: ["string", "null"] description: Optional contextual text shown alongside the question. example: Latest draft QuestionType: description: The interaction type of a human-in-the-loop question. type: string enum: - yes_no - multiple_choice - multi_select - freeform - confirmation SubmitAnswerRequest: description: > Request body for submitting an answer to a pending question. At least one of `value`, `selected_option_key`, or `selected_option_keys` must be provided. type: object properties: value: type: string description: Freeform answer text. example: "Yes, proceed with the changes." selected_option_key: type: string description: Key of the selected option (for single-select multiple-choice questions). example: option_a selected_option_keys: type: array items: type: string description: Keys of selected options (for multi-select questions). example: ["option_a", "option_b"] ErrorResponseEntry: description: A single error entry in an error response. type: object required: - status - title - detail properties: status: type: string description: HTTP status code as a string. example: "404" title: type: string description: Short error classification. example: Not Found detail: type: string description: Human-readable error description. example: Run not found. code: type: string description: Optional machine-readable error code for structured client handling. example: access_token_expired ErrorResponse: description: Standard error response containing one or more error entries. type: object required: - errors properties: errors: type: array description: List of error entries. items: $ref: "#/components/schemas/ErrorResponseEntry" leftover_env_keys: type: array description: >- Optional list of runtime env keys that were written before an install failure. Currently populated by `POST /install/finish` failure responses only. items: type: string removed_env_keys: type: array description: >- Optional list of runtime env keys that were actually removed before an install failure. Currently populated by `POST /install/finish` failure responses only. items: type: string ActorKind: description: High-level category of an event actor. type: string enum: - user - agent - system ActorRef: description: > Optional primary actor associated with a run event. Present on control actions and durable agent output where a stable user or agent identity matters; omitted on routine runtime lifecycle events. type: object required: - kind properties: kind: $ref: "#/components/schemas/ActorKind" id: type: string description: Stable actor identifier when available. display: type: string description: Display-friendly label for the actor. RunEvent: description: > Internal RunEvent-compatible JSON payload. The server validates this body by deserializing into the typed RunEvent struct. type: object required: - id - ts - run_id - event properties: id: type: string ts: type: string format: date-time run_id: type: string node_id: type: ["string", "null"] node_label: type: ["string", "null"] stage_id: type: ["string", "null"] description: Stage execution identity, formatted as "{node_id}@{visit}". parallel_group_id: type: ["string", "null"] description: > Durable identity of one execution of a parallel node, formatted as "{node_id}@{visit}". parallel_branch_id: type: ["string", "null"] description: > Durable identity of one branch within a parallel execution, formatted as "{parallel_group_id}:{index}". session_id: type: ["string", "null"] parent_session_id: type: ["string", "null"] tool_call_id: type: ["string", "null"] description: > Stable identifier for a tool call, present on agent.tool.* events and other durable events that directly describe the same tool call. actor: oneOf: - $ref: "#/components/schemas/ActorRef" - type: "null" event: type: string description: Event type discriminator. example: stage.started properties: type: object additionalProperties: true additionalProperties: true RunSupersededByProps: description: Properties for the `run.superseded_by` audit event emitted on a rewound source run after archive succeeds. type: object required: - new_run_id - target_checkpoint_ordinal - target_node_id - target_visit properties: new_run_id: type: string target_checkpoint_ordinal: type: integer minimum: 1 target_node_id: type: string target_visit: type: integer minimum: 1 EventSeq: description: Assigned sequence number component of a stored event envelope. type: object required: - seq properties: seq: type: integer description: Assigned event sequence number. example: 42 EventEnvelope: description: > Stored event envelope with assigned sequence number. On the wire the envelope is flattened: seq sits alongside the RunEvent payload fields at the top level of the JSON object. allOf: - $ref: "#/components/schemas/EventSeq" - $ref: "#/components/schemas/RunEvent" PaginatedEventList: description: Paginated list of stored run events. type: object required: - data - meta properties: data: type: array items: $ref: "#/components/schemas/EventEnvelope" meta: $ref: "#/components/schemas/PaginationMeta" AppendEventResponse: description: Assigned sequence number for an appended event. type: object required: - seq properties: seq: type: integer description: Assigned event sequence number. example: 42 WriteBlobResponse: description: Content-addressed identifier for a stored blob. type: object required: - id properties: id: type: string description: Blob identifier. example: 550e8400-e29b-41d4-a716-446655440000 ArtifactEntry: description: A single artifact filename. type: object required: - filename properties: filename: type: string description: Artifact filename. example: src/lib.rs ArtifactListResponse: description: List of artifact filenames for a stage. type: object required: - data properties: data: type: array items: $ref: "#/components/schemas/ArtifactEntry" ArtifactBatchUploadEntry: description: One file entry in a strict multipart artifact upload manifest. type: object required: - part - path properties: part: type: string description: Multipart field name for the file part. example: file1 path: type: string description: Relative artifact path to store. example: src/lib.rs sha256: type: ["string", "null"] description: Optional lowercase hex SHA-256 checksum for the file contents. example: 3f785df4c5b7d3f1f4c1f0ecb0f55f1d9f6f6a3d9f0a8a98f7a74f29d1f81a2c expected_bytes: type: ["integer", "null"] format: int64 minimum: 0 description: Optional exact byte length expected for the file part. example: 1234 content_type: type: ["string", "null"] description: Optional client-supplied content type for the file part. example: text/plain ArtifactBatchUploadManifest: description: Manifest for strict multipart artifact uploads. type: object required: - entries properties: entries: type: array minItems: 1 items: $ref: "#/components/schemas/ArtifactBatchUploadEntry" RunArtifactEntry: description: A captured artifact file for a run. type: object required: - stage_id - node_slug - retry - relative_path - size properties: stage_id: type: string description: Stage ID in `node@visit` form. node_slug: type: string description: Node slug that produced the artifact. retry: type: integer format: int32 description: Retry attempt number. relative_path: type: string description: Artifact path relative to the stage artifact capture directory. size: type: integer format: int64 description: Artifact size in bytes. RunArtifactListResponse: description: List of captured artifact files for a run. type: object required: - data properties: data: type: array items: $ref: "#/components/schemas/RunArtifactEntry" BlockedReason: description: Specific reason a run is blocked on external intervention. type: string enum: - human_input_required RunControlAction: description: Run control action requested by the API. type: string enum: - cancel - pause - unpause InternalStageStatus: description: Internal stage status from outcomes and node status records. type: string enum: - success - fail - skipped - partial_success - retry NodeStatusRecord: description: Internal node status record. type: object required: - status - timestamp properties: status: $ref: "#/components/schemas/InternalStageStatus" notes: type: ["string", "null"] failure_reason: type: ["string", "null"] timestamp: type: string format: date-time NodeState: description: Internal node projection state. type: object properties: prompt: type: ["string", "null"] response: type: ["string", "null"] status: oneOf: - $ref: "#/components/schemas/NodeStatusRecord" - type: "null" provider_used: {} diff: type: ["string", "null"] script_invocation: {} script_timing: {} parallel_results: {} stdout: type: ["string", "null"] stderr: type: ["string", "null"] PendingInterviewRecord: description: Pending interview question plus the time it entered the unresolved set. type: object properties: question: $ref: "#/components/schemas/ApiQuestion" started_at: type: ["string", "null"] format: date-time RunProjection: description: Raw internal run projection derived from the event log. type: object required: - nodes properties: spec: type: ["object", "null"] additionalProperties: true graph_source: type: ["string", "null"] start: type: ["object", "null"] additionalProperties: true status: oneOf: - $ref: "#/components/schemas/RunStatus" - type: "null" status_updated_at: oneOf: - type: string format: date-time - type: "null" checkpoint: oneOf: - $ref: "#/components/schemas/RunCheckpoint" - type: "null" checkpoints: type: array description: Sequence-tagged checkpoint history entries as `[seq, checkpoint]`. items: type: array minItems: 2 maxItems: 2 items: oneOf: - type: integer - $ref: "#/components/schemas/RunCheckpoint" conclusion: type: ["object", "null"] additionalProperties: true retro: type: ["object", "null"] additionalProperties: true retro_prompt: type: ["string", "null"] retro_response: type: ["string", "null"] sandbox: type: ["object", "null"] additionalProperties: true final_patch: type: ["string", "null"] pull_request: type: ["object", "null"] additionalProperties: true superseded_by: type: ["string", "null"] pending_interviews: type: object additionalProperties: $ref: "#/components/schemas/PendingInterviewRecord" nodes: type: object description: Map from StageId (`node_id@visit`) to NodeState. additionalProperties: $ref: "#/components/schemas/NodeState" StoreRunSummary: description: Durable run summary derived from the backing store. type: object required: - run_id - goal - title - labels - status - repository - created_at properties: run_id: type: string workflow_name: type: ["string", "null"] workflow_slug: type: ["string", "null"] goal: type: string title: type: string labels: type: object additionalProperties: type: string host_repo_path: type: ["string", "null"] repository: $ref: "#/components/schemas/RepositoryReference" start_time: type: ["string", "null"] format: date-time created_at: type: string format: date-time status: $ref: "#/components/schemas/RunStatus" pending_control: oneOf: - $ref: "#/components/schemas/RunControlAction" - type: "null" duration_ms: type: ["integer", "null"] format: int64 minimum: 0 elapsed_secs: type: ["number", "null"] total_usd_micros: type: ["integer", "null"] format: int64 superseded_by: type: ["string", "null"] ForkRequest: description: Request body for creating a new run from a source run checkpoint. type: object properties: target: type: ["string", "null"] description: Optional checkpoint target such as `@2`, `build`, or `build@1`. Defaults to the latest checkpoint. push: type: ["boolean", "null"] description: Whether to push the new run branches. Defaults to true. ForkResponse: description: Response returned after creating a forked run. type: object required: - source_run_id - new_run_id - target properties: source_run_id: type: string new_run_id: type: string target: type: string RewindRequest: description: Request body for creating a replacement run from a source run checkpoint. type: object properties: target: type: ["string", "null"] description: Optional checkpoint target such as `@2`, `build`, or `build@1`. Defaults to the latest checkpoint. push: type: ["boolean", "null"] description: Whether to push the new run branches. Defaults to true. RewindResponse: description: Response returned after rewind creates a new run. type: object required: - source_run_id - new_run_id - target - archived properties: source_run_id: type: string new_run_id: type: string target: type: string archived: type: boolean archive_error: type: ["string", "null"] TimelineEntryResponse: description: Checkpoint timeline entry for a run. type: object required: - ordinal - node_name - visit properties: ordinal: type: integer minimum: 1 node_name: type: string visit: type: integer minimum: 1 run_commit_sha: type: ["string", "null"] # ── Run Board Schemas ──────────────────────────────────────────────── BoardColumn: description: Board column status for a run in the list view. type: string enum: - initializing - running - blocked - succeeded - failed BoardColumnDefinition: type: object required: - id - name properties: id: type: string name: type: string CheckRunStatus: description: Status of a CI check run. type: string enum: - success - failure - skipped - pending - queued CheckRun: description: A CI check run result associated with a run's pull request. type: object required: - name - status properties: name: type: string description: Name of the CI check. example: unit-tests status: $ref: "#/components/schemas/CheckRunStatus" duration_secs: type: number description: Duration of the check run in seconds. example: 154.0 # ── Reusable Sub-Schemas ─────────────────────────────────────────── ModelReference: description: Reference to a model by its identifier. type: object required: - id properties: id: type: string description: Model identifier. example: claude-opus-4-6 WorkflowReference: description: Reference to a workflow by its slug. type: object required: - slug properties: slug: type: string description: URL-safe workflow slug. example: implement RunReference: description: Reference to a run with its title. type: object required: - id - title properties: id: type: string description: Unique run identifier. example: run-047 title: type: string description: Human-readable run title. example: "PR #312 — Add OAuth2 PKCE flow" RepositoryReference: description: Reference to a repository by name. type: object required: - name properties: name: type: string description: Repository name. example: api-server BilledTokenCounts: description: Token counts with optional billed USD micros totals. type: object required: - input_tokens - output_tokens - total_tokens properties: input_tokens: type: integer description: Number of input tokens consumed. example: 28640 output_tokens: type: integer description: Number of output tokens generated. example: 8750 total_tokens: type: integer description: Total billable tokens aggregated across categories. example: 37390 reasoning_tokens: type: integer description: Number of reasoning tokens. example: 1200 cache_read_tokens: type: integer description: Number of cache read tokens. example: 4800 cache_write_tokens: type: integer description: Number of cache write tokens. example: 1500 total_usd_micros: type: ["integer", "null"] format: int64 description: Billed USD amount in micros. example: 720000 CodeLocation: description: A file and line location in the codebase. type: object required: - file properties: file: type: string description: File path. example: src/middleware/rate-limit.ts line: type: integer description: Line number in the file. example: 42 RunError: description: Error information for a failed run. type: object required: - message properties: message: type: string description: Error message. example: "Stage 'apply-changes' exceeded maximum retries." RunPullRequest: description: Pull request information for a run. type: object required: - number properties: number: type: integer description: Pull request number. example: 889 additions: type: integer description: Lines added. example: 234 deletions: type: integer description: Lines deleted. example: 67 comments: type: integer description: Number of review comments. example: 4 checks: type: array description: CI check run results. items: $ref: "#/components/schemas/CheckRun" PullRequestRecord: description: Persisted record of a pull request created for a run. type: object required: - html_url - number - owner - repo - base_branch - head_branch - title properties: html_url: type: string format: uri example: https://github.com/fabro-sh/fabro/pull/123 number: type: integer example: 123 owner: type: string example: fabro-sh repo: type: string example: fabro base_branch: type: string example: main head_branch: type: string example: fabro/run/demo title: type: string example: Move PR commands server-side PullRequestUser: description: GitHub user summary for a pull request. type: object required: - login properties: login: type: string example: octocat PullRequestRef: description: Git reference summary for a pull request. type: object required: - ref properties: ref: type: string example: fabro/run/demo PullRequestDetail: description: Stored pull request record plus live GitHub fields. type: object required: - record - number - title - state - draft - merged - additions - deletions - changed_files - html_url - user - head - base - created_at - updated_at properties: record: $ref: "#/components/schemas/PullRequestRecord" number: type: integer example: 123 title: type: string example: Move PR commands server-side body: type: ["string", "null"] example: | ## Summary - Move PR commands server-side state: type: string example: open draft: type: boolean example: false merged: type: boolean example: false merged_at: type: ["string", "null"] format: date-time example: "2026-04-23T15:45:00Z" mergeable: type: ["boolean", "null"] example: true additions: type: integer example: 234 deletions: type: integer example: 67 changed_files: type: integer example: 5 html_url: type: string format: uri example: https://github.com/fabro-sh/fabro/pull/123 user: $ref: "#/components/schemas/PullRequestUser" head: $ref: "#/components/schemas/PullRequestRef" base: $ref: "#/components/schemas/PullRequestRef" created_at: type: string format: date-time example: "2026-04-23T15:40:00Z" updated_at: type: string format: date-time example: "2026-04-23T15:45:00Z" CreateRunPullRequestRequest: description: Request body for creating a run pull request. type: object required: - force properties: force: type: boolean description: Create the pull request even if the run did not finish with success or partial_success. example: false model: type: ["string", "null"] description: Optional model override for generating the pull request description. example: claude-sonnet-4-6 MergeMethod: description: GitHub merge method for a pull request. type: string enum: - merge - squash - rebase MergeRunPullRequestRequest: description: Request body for merging a run pull request. type: object required: - method properties: method: $ref: "#/components/schemas/MergeMethod" MergeRunPullRequestResponse: description: Response body for merging a run pull request. type: object required: - number - html_url - method properties: number: type: integer example: 123 html_url: type: string format: uri example: https://github.com/fabro-sh/fabro/pull/123 method: $ref: "#/components/schemas/MergeMethod" CloseRunPullRequestResponse: description: Response body for closing a run pull request. type: object required: - number - html_url properties: number: type: integer example: 123 html_url: type: string format: uri example: https://github.com/fabro-sh/fabro/pull/123 RunTimings: description: Timing information for a run. type: object required: - elapsed_secs properties: elapsed_secs: type: number description: Wall-clock time elapsed in seconds. example: 420.0 elapsed_warning: type: boolean description: Whether the elapsed time exceeds the expected threshold. example: false SandboxResources: description: Compute resources allocated to a sandbox. type: object required: - cpu - memory properties: cpu: type: integer description: Number of CPU cores. example: 4 memory: type: integer description: Memory in GB. example: 8 RunSandbox: description: Sandbox environment for a run. type: object required: - id properties: id: type: string description: Sandbox identifier. example: sb-a1b2c3d4 resources: $ref: "#/components/schemas/SandboxResources" RunQuestion: description: A pending human-in-the-loop question summary. type: object required: - text properties: text: type: string description: Question text. example: Accept or push for another round? AggregateBillingTotals: description: Aggregate billing totals across all runs. type: object required: - runs - input_tokens - output_tokens - total_tokens - runtime_secs properties: runs: type: integer description: Total number of completed runs. example: 9 input_tokens: type: integer description: Total input tokens. example: 643860 output_tokens: type: integer description: Total output tokens. example: 189720 total_tokens: type: integer description: Total tokens aggregated across all billing categories. example: 833580 reasoning_tokens: type: integer description: Total reasoning tokens. example: 12040 cache_read_tokens: type: integer description: Total cache read tokens. example: 85400 cache_write_tokens: type: integer description: Total cache write tokens. example: 9200 total_usd_micros: type: ["integer", "null"] format: int64 description: Total billed USD amount in micros. example: 20340000 runtime_secs: type: number description: Total runtime in seconds. example: 3501.0 BillingStageRef: description: Reference to a billing stage. type: object required: - id - name properties: id: type: string description: Stage identifier (slug). example: propose-changes name: type: string description: Human-readable stage name. example: Propose Changes # ── Run Board Schemas (updated) ───────────────────────────────────── RunListItem: description: Canonical run summary shown in the board view, extended with board-specific metadata. type: object required: - run_id - goal - title - status - labels - repository - created_at - column properties: run_id: type: string description: Unique run identifier (ULID). example: 01JNQVR7M0EJ5GKAT2SC4ERS1Z workflow_name: type: ["string", "null"] workflow_slug: type: ["string", "null"] goal: type: string repository: $ref: "#/components/schemas/RepositoryReference" title: type: string description: Human-readable title describing the run's goal. example: Add rate limiting to auth endpoints status: $ref: "#/components/schemas/RunStatus" labels: type: object additionalProperties: type: string host_repo_path: type: ["string", "null"] start_time: type: ["string", "null"] format: date-time pending_control: oneOf: - $ref: "#/components/schemas/RunControlAction" - type: "null" duration_ms: type: ["integer", "null"] format: int64 minimum: 0 elapsed_secs: type: ["number", "null"] total_usd_micros: type: ["integer", "null"] format: int64 column: $ref: "#/components/schemas/BoardColumn" pull_request: $ref: "#/components/schemas/RunPullRequest" sandbox: $ref: "#/components/schemas/RunSandbox" question: $ref: "#/components/schemas/RunQuestion" created_at: type: string format: date-time description: Timestamp when the run was created. example: "2026-03-06T14:30:00Z" RunCheckpoint: description: Serializable snapshot of execution state for crash recovery and resume. type: object required: - timestamp - current_node - completed_nodes - node_retries - context_values properties: timestamp: type: string format: date-time description: ISO 8601 timestamp when the checkpoint was created. current_node: type: string description: Identifier of the node being executed at checkpoint time. completed_nodes: type: array items: type: string description: Identifiers of nodes that have completed execution. node_retries: type: object additionalProperties: type: integer description: Map of node identifier to retry count. context_values: type: object additionalProperties: true description: Key-value context map accumulated during execution. node_outcomes: type: object additionalProperties: true description: Map of node identifier to outcome data for goal gate checks after resume. next_node_id: type: string description: The node to resume execution at after this checkpoint. git_commit_sha: type: string description: SHA of the git commit created at this checkpoint. loop_failure_signatures: type: object additionalProperties: true description: Failure signature counts within the main loop. restart_failure_signatures: type: object additionalProperties: true description: Failure signature counts across loop_restart edges. # ── Stage / Turn Schemas ───────────────────────────────────────────── StageStatus: description: Execution status of a workflow stage. type: string enum: - completed - running - pending - failed - cancelled RunStage: description: A single stage in a run's workflow graph. type: object required: - id - name - status properties: id: type: string description: Unique stage identifier within the run. example: propose-changes name: type: string description: Human-readable stage name. example: Propose Changes status: $ref: "#/components/schemas/StageStatus" duration_secs: type: number description: Time spent in this stage, in seconds. example: 154.0 dot_id: type: string description: Node identifier in the Graphviz graph source. example: propose ToolUse: description: A single tool invocation with its input, result, and execution metadata. type: object required: - id - tool_name - input - result - is_error properties: id: type: string description: Unique identifier for this tool invocation. Enables correlation in parallel tool use. example: toolu_01A09q90qw90lq917835lq9 tool_name: type: string description: Name of the tool that was invoked. example: read_file input: type: string description: JSON-encoded input passed to the tool. example: '{ "path": "src/routes/auth.ts" }' result: type: string description: Output returned by the tool. Contains the error message when is_error is true. example: 'import { Router } from "express";' is_error: type: boolean description: Whether the tool invocation failed. When true, the result field contains the error message. example: false duration_ms: type: integer description: Wall-clock execution time of the tool invocation in milliseconds. example: 142 StageTurn: description: A single turn in a stage conversation — a system prompt, assistant response, or tool invocation block. discriminator: propertyName: kind mapping: system: "#/components/schemas/SystemStageTurn" assistant: "#/components/schemas/AssistantStageTurn" tool: "#/components/schemas/ToolStageTurn" oneOf: - $ref: "#/components/schemas/SystemStageTurn" - $ref: "#/components/schemas/AssistantStageTurn" - $ref: "#/components/schemas/ToolStageTurn" SystemStageTurn: description: A system prompt turn that sets the stage's instructions. type: object required: - kind - content properties: kind: type: string enum: [system] content: type: string description: System prompt text. example: You are a drift detection agent. Compare the production and staging environments. AssistantStageTurn: description: An assistant response turn within a stage. type: object required: - kind - content properties: kind: type: string enum: [assistant] content: type: string description: Assistant response text. example: I'll start by loading the environment configurations for both production and staging. ToolStageTurn: description: A tool invocation turn containing one or more tool calls. type: object required: - kind - tools properties: kind: type: string enum: [tool] content: type: string description: Text accompanying the tool invocations, or null when the turn contains only tool calls. tools: type: array description: Tool invocations executed in this turn. items: $ref: "#/components/schemas/ToolUse" # ── File Diff Schemas ────────────────────────────────────────────── FileCheckpoint: description: A named checkpoint within a run, used to filter file diffs. type: object required: - id - label properties: id: type: string description: Checkpoint identifier. example: cp-3 label: type: string description: Human-readable label for the checkpoint. example: "Checkpoint 3 — Review Changes" DiffFile: description: A file's contents at one side of a diff. type: object required: - name - contents properties: name: type: string description: File path relative to the repository root. example: src/commands/run.ts contents: type: string description: Full file contents. Empty string for newly created or deleted files. example: 'import { parseArgs } from "node:util";' FileDiff: description: | A before/after pair showing changes to a single file. Contents conventions for non-modify cases: - Added: `old_file.contents` is empty string; `new_file` holds the added contents. - Deleted: `new_file.contents` is empty string; `old_file` holds the removed contents. - Renamed (no content change): both sides hold identical contents; `old_file.name != new_file.name`. - Symlink / submodule / binary / sensitive / truncated: contents are empty strings; consumers must render a placeholder based on the flag set. type: object required: - old_file - new_file properties: old_file: $ref: "#/components/schemas/DiffFile" new_file: $ref: "#/components/schemas/DiffFile" change_kind: type: string description: Optional classification of the change. Clients that don't recognize a value should fall back to inspecting the old/new contents. enum: - added - modified - deleted - renamed - symlink - submodule example: modified truncated: type: boolean description: When `true`, `new_file.contents` and `old_file.contents` are empty strings because the file exceeded a cap (see `truncation_reason`). example: false truncation_reason: type: string description: Reason this file's contents were omitted. Absent when `truncated` is `false` or omitted. enum: - file_too_large - budget_exhausted binary: type: boolean description: When `true`, the file is non-textual; `contents` on both sides are empty strings. example: false sensitive: type: boolean description: When `true`, the file path matched the server's sensitive-path denylist; `contents` on both sides are empty strings regardless of truncation or binary flags. example: false DiffStats: description: | Aggregate `+/-` line counts across all files in a diff (or the unified patch in degraded mode). Binary, sensitive, symlink, and submodule files contribute 0/0 since they have no line-level diff. Both fields are 0 for empty / pre-start envelopes. type: object required: - additions - deletions properties: additions: type: integer description: Total lines added. example: 567 deletions: type: integer description: Total lines deleted. example: 234 RunFilesMeta: description: | Metadata for a `PaginatedRunFileList` response. Replaces `PaginationMeta` on the files endpoint — the naturally-bounded list does not use cursor pagination but exposes caps and a degraded-response path instead. type: object required: - truncated - total_changed - stats properties: stats: $ref: "#/components/schemas/DiffStats" truncated: type: boolean description: True when any cap (file count, per-file size, or aggregate size) was hit for this response. example: false files_omitted_by_budget: type: integer description: Number of files dropped because the aggregate 5 MiB budget was exhausted. Zero or absent when no files were dropped for budget reasons. example: 0 total_changed: type: integer description: Total files changed in the run (before caps were applied). May exceed `data.length` when truncation occurred. example: 3 to_sha: type: string description: Head SHA the diff (or patch) was resolved against. pattern: "^[0-9a-f]{7,40}$" example: "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0" to_sha_committed_at: type: string format: date-time description: Commit time of `to_sha`, used by the UI for the "Checkpoint Xm ago" freshness label on Running runs. degraded: type: boolean description: When `true`, this response carries only a unified patch string in `patch` (no per-file contents in `data`). The UI should render via a unified-patch component. example: false degraded_reason: type: string description: Why the response degraded to patch-only form. Absent when `degraded` is `false` or omitted. enum: - sandbox_unreachable - sandbox_gone - provider_unsupported patch: type: string description: Unified-patch text captured at run end. Present only when `degraded` is `true`. Capped at 5 MiB; denylisted file sections are stripped and replaced with a placeholder line. PaginatedRunFileList: description: | List of file diffs produced by a run, with metadata describing truncation and degraded-response state. Naturally bounded: at most 200 files per response. Consumers should inspect `meta.truncated` rather than assuming `data.length` equals the run's total change count. type: object required: - data - meta properties: data: type: array items: $ref: "#/components/schemas/FileDiff" meta: $ref: "#/components/schemas/RunFilesMeta" # ── Billing Schemas ────────────────────────────────────────────────── RunBillingStage: description: Token counts and billed totals for a single stage within a run. type: object required: - stage - model - billing - runtime_secs properties: stage: $ref: "#/components/schemas/BillingStageRef" model: $ref: "#/components/schemas/ModelReference" billing: $ref: "#/components/schemas/BilledTokenCounts" runtime_secs: type: number description: Wall-clock runtime in seconds. example: 154.0 RunBillingTotals: description: Aggregate billing totals across all stages of a run. type: object required: - runtime_secs - input_tokens - output_tokens - total_tokens properties: runtime_secs: type: number description: Total wall-clock runtime in seconds. example: 389.0 input_tokens: type: integer description: Total input tokens consumed. example: 71540 output_tokens: type: integer description: Total output tokens generated. example: 21080 total_tokens: type: integer description: Total tokens aggregated across all billing categories. example: 92620 reasoning_tokens: type: integer description: Total reasoning tokens. example: 3400 cache_read_tokens: type: integer description: Total cache read tokens. example: 22000 cache_write_tokens: type: integer description: Total cache write tokens. example: 4500 total_usd_micros: type: ["integer", "null"] format: int64 description: Total billed USD amount in micros. example: 2260000 BillingByModel: description: Billing statistics grouped by model. type: object required: - model - stages - billing properties: model: $ref: "#/components/schemas/ModelReference" stages: type: integer description: Number of stages that used this model. example: 2 billing: $ref: "#/components/schemas/BilledTokenCounts" RunBilling: description: Complete billing breakdown for a single run. type: object required: - stages - totals - by_model properties: stages: type: array description: Per-stage billing breakdown. items: $ref: "#/components/schemas/RunBillingStage" totals: $ref: "#/components/schemas/RunBillingTotals" by_model: type: array description: Billing grouped by model. items: $ref: "#/components/schemas/BillingByModel" AggregateBilling: description: Aggregate token counts and billed totals across all runs since server start. type: object required: - totals - by_model properties: totals: $ref: "#/components/schemas/AggregateBillingTotals" by_model: type: array description: Billing grouped by model. items: $ref: "#/components/schemas/BillingByModel" PreviewUrlRequest: description: Request body for generating a preview URL from a sandbox port. type: object required: - port - expires_in_secs properties: port: type: integer description: Port number exposed by the sandbox. example: 3000 expires_in_secs: type: integer description: Time-to-live for the preview URL in seconds. minimum: 1 maximum: 86400 example: 3600 signed: type: boolean description: When true, return a signed URL that does not require a preview token header. default: false PreviewUrlResponse: description: Response containing the generated preview URL. type: object required: - url properties: url: type: string description: Preview URL. example: "https://preview.example.com/sb-a1b2c3d4/3000" token: type: string description: Preview token header value for unsigned preview URLs. example: "preview-token-123" SshAccessRequest: description: Request body for creating SSH access for a sandbox-backed run. type: object required: - ttl_minutes properties: ttl_minutes: type: number description: Time-to-live for the SSH command in minutes. minimum: 1 maximum: 1440 example: 60 SshAccessResponse: description: Response containing an SSH command for the sandbox. type: object required: - command properties: command: type: string description: SSH command to connect to the sandbox. example: ssh daytona@preview.example.com -p 2222 SandboxFileEntry: description: A directory entry in a run sandbox. type: object required: - name - is_dir properties: name: type: string description: Basename of the entry. is_dir: type: boolean description: Whether the entry is a directory. size: type: integer format: int64 description: File size in bytes when known. SandboxFileListResponse: description: Non-paginated list of sandbox directory entries. type: object required: - data properties: data: type: array items: $ref: "#/components/schemas/SandboxFileEntry" # ── Insights Schemas ───────────────────────────────────────────────── SavedQuery: description: A saved SQL query for the insights editor. type: object required: - id - name - sql - created_at - updated_at properties: id: type: string description: Unique query identifier. example: "1" name: type: string description: Human-readable query name. example: Run duration by workflow sql: type: string description: SQL query text. example: "SELECT workflow_name, AVG(duration_seconds) FROM runs GROUP BY 1" created_at: type: string format: date-time description: Timestamp when the query was saved. example: "2026-03-01T10:00:00Z" updated_at: type: string format: date-time description: Timestamp when the query was last modified. example: "2026-03-05T14:30:00Z" SaveQueryRequest: description: Request body for creating or updating a saved query. type: object required: - name - sql properties: name: type: string description: Human-readable query name. example: Run duration by workflow sql: type: string description: SQL query text. example: "SELECT workflow_name, AVG(duration_seconds) FROM runs GROUP BY 1" ExecuteQueryRequest: description: Request body for executing an ad-hoc SQL query. type: object required: - sql properties: sql: type: string description: SQL query to execute. example: "SELECT workflow_name, COUNT(*) FROM runs GROUP BY 1" ExecuteQueryResponse: description: Columnar result set from an executed query. type: object required: - columns - rows - elapsed - row_count properties: columns: type: array description: Column names in the result set. items: type: string example: ["workflow_name", "count"] rows: type: array description: Result rows, each an array of values matching the column order. items: type: array items: oneOf: - type: string - type: number - type: boolean - type: "null" elapsed: type: number description: Query execution time in seconds. example: 0.342 row_count: type: integer description: Number of rows returned. example: 3 HistoryEntry: description: A previously executed query in the history log. type: object required: - id - sql - timestamp - elapsed - row_count properties: id: type: string description: Unique history entry identifier. example: h1 sql: type: string description: SQL query that was executed. example: "SELECT workflow_name, COUNT(*) FROM runs GROUP BY 1" timestamp: type: string format: date-time description: ISO 8601 timestamp of execution. example: "2025-09-15T14:00:00Z" elapsed: type: number description: Query execution time in seconds. example: 0.342 row_count: type: integer description: Number of rows returned. example: 6 # ── Settings Schemas ───────────────────────────────────────────────── ServerSettings: description: Current in-memory server settings view. type: object required: [server, features] properties: server: $ref: "#/components/schemas/ServerNamespace" features: $ref: "#/components/schemas/FeaturesNamespace" ServerNamespace: type: object required: - listen - api - web - auth - ip_allowlist - storage - artifacts - slatedb - scheduler - logging - integrations properties: listen: $ref: "#/components/schemas/ServerListenSettings" api: $ref: "#/components/schemas/ServerApiSettings" web: $ref: "#/components/schemas/ServerWebSettings" auth: $ref: "#/components/schemas/ServerAuthSettings" ip_allowlist: $ref: "#/components/schemas/ServerIpAllowlistSettings" storage: $ref: "#/components/schemas/ServerStorageSettings" artifacts: $ref: "#/components/schemas/ServerArtifactsSettings" slatedb: $ref: "#/components/schemas/ServerSlateDbSettings" scheduler: $ref: "#/components/schemas/ServerSchedulerSettings" logging: $ref: "#/components/schemas/ServerLoggingSettings" integrations: $ref: "#/components/schemas/ServerIntegrationsSettings" FeaturesNamespace: type: object required: [session_sandboxes] properties: session_sandboxes: type: boolean ServerListenSettings: oneOf: - $ref: "#/components/schemas/ServerListenTcpSettings" - $ref: "#/components/schemas/ServerListenUnixSettings" ServerListenTcpSettings: type: object required: [type, address] properties: type: type: string enum: [tcp] address: type: string ServerListenUnixSettings: type: object required: [type, path] properties: type: type: string enum: [unix] path: type: string ServerApiSettings: type: object required: [url] properties: url: type: ["string", "null"] ServerWebSettings: type: object required: [enabled, url] properties: enabled: type: boolean url: type: string ServerAuthSettings: type: object required: [methods, github] properties: methods: type: array items: $ref: "#/components/schemas/ServerAuthMethod" github: $ref: "#/components/schemas/ServerAuthGithubSettings" ServerAuthMethod: type: string enum: [dev-token, github] ServerAuthGithubSettings: type: object required: [allowed_usernames] properties: allowed_usernames: type: array items: type: string ServerIpAllowlistSettings: type: object required: [entries, trusted_proxy_count] properties: entries: type: array items: $ref: "#/components/schemas/IpAllowEntry" trusted_proxy_count: type: integer ServerIpAllowlistOverrideSettings: type: object required: [entries, trusted_proxy_count] properties: entries: type: ["array", "null"] items: $ref: "#/components/schemas/IpAllowEntry" trusted_proxy_count: type: ["integer", "null"] IpAllowEntry: oneOf: - $ref: "#/components/schemas/LiteralIpAllowEntry" - $ref: "#/components/schemas/GitHubMetaHooksEntry" LiteralIpAllowEntry: type: object required: [Literal] properties: Literal: type: string GitHubMetaHooksEntry: type: string enum: [GitHubMetaHooks] ServerStorageSettings: type: object required: [root] properties: root: type: string ServerArtifactsSettings: type: object required: [prefix, store] properties: prefix: type: string store: $ref: "#/components/schemas/ObjectStoreSettings" ServerSlateDbSettings: type: object required: [prefix, store, flush_interval, disk_cache] properties: prefix: type: string store: $ref: "#/components/schemas/ObjectStoreSettings" flush_interval: type: string disk_cache: type: boolean ObjectStoreSettings: oneOf: - $ref: "#/components/schemas/ObjectStoreLocalSettings" - $ref: "#/components/schemas/ObjectStoreS3Settings" ObjectStoreLocalSettings: type: object required: [type, root] properties: type: type: string enum: [local] root: type: string ObjectStoreS3Settings: type: object required: [type, bucket, region, endpoint, path_style] properties: type: type: string enum: [s3] bucket: type: string region: type: string endpoint: type: ["string", "null"] path_style: type: boolean ServerSchedulerSettings: type: object required: [max_concurrent_runs] properties: max_concurrent_runs: type: integer ServerLoggingSettings: type: object required: [level] properties: level: type: ["string", "null"] ServerIntegrationsSettings: type: object required: [github, slack, discord, teams] properties: github: $ref: "#/components/schemas/GithubIntegrationSettings" slack: $ref: "#/components/schemas/SlackIntegrationSettings" discord: $ref: "#/components/schemas/DiscordIntegrationSettings" teams: $ref: "#/components/schemas/TeamsIntegrationSettings" GithubIntegrationSettings: type: object required: - enabled - strategy - app_id - client_id - slug - permissions - webhooks properties: enabled: type: boolean strategy: $ref: "#/components/schemas/GithubIntegrationStrategy" app_id: type: ["string", "null"] client_id: type: ["string", "null"] slug: type: ["string", "null"] permissions: type: object additionalProperties: type: string webhooks: oneOf: - $ref: "#/components/schemas/IntegrationWebhooksSettings" - type: "null" GithubIntegrationStrategy: type: string enum: [token, app] SlackIntegrationSettings: type: object required: [enabled, default_channel] properties: enabled: type: boolean default_channel: type: ["string", "null"] DiscordIntegrationSettings: type: object required: [enabled] properties: enabled: type: boolean TeamsIntegrationSettings: type: object required: [enabled] properties: enabled: type: boolean IntegrationWebhooksSettings: type: object required: [strategy, ip_allowlist] properties: strategy: oneOf: - $ref: "#/components/schemas/WebhookStrategy" - type: "null" ip_allowlist: oneOf: - $ref: "#/components/schemas/ServerIpAllowlistOverrideSettings" - type: "null" WebhookStrategy: type: string enum: [tailscale_funnel, server_url] WorkflowSettings: description: | The persisted dense `WorkflowSettings` snapshot used for a specific run. This matches the resolved run settings recorded at launch time. type: object additionalProperties: true SystemInfoResponse: description: Runtime information for the active Fabro server process. type: object properties: version: type: string description: Server version string. git_sha: type: ["string", "null"] description: Build git SHA when available. build_date: type: ["string", "null"] description: Build date when available. profile: type: ["string", "null"] description: Cargo build profile (e.g. `release`, `debug`) when available. os: type: string description: Target operating system. arch: type: string description: Target CPU architecture. storage_engine: type: string description: Backing run storage engine. storage_dir: type: string description: Configured storage directory. uptime_secs: type: integer format: int64 description: Seconds since this server process started. runs: $ref: "#/components/schemas/SystemRunCounts" sandbox_provider: type: string description: Effective sandbox provider for launched runs. features: $ref: "#/components/schemas/SystemFeatures" SystemFeatures: description: Server-level capability flags. type: object properties: session_sandboxes: type: boolean description: Whether session sandboxes are enabled. retros: type: boolean description: Whether workflow retros are enabled. SystemRunCounts: description: Counts of known runs in the active server process. type: object properties: total: type: integer format: int64 description: Total runs tracked by the server process. active: type: integer format: int64 description: Runs currently queued or executing. DiskUsageResponse: description: Disk usage summary for server-managed data. type: object properties: summary: type: array items: $ref: "#/components/schemas/DiskUsageSummaryRow" total_size_bytes: type: integer format: int64 description: Total size of all tracked system data. total_reclaimable_bytes: type: integer format: int64 description: Total bytes reclaimable by deleting inactive runs and logs. runs: type: ["array", "null"] description: Per-run usage rows when verbose output is requested. items: $ref: "#/components/schemas/DiskUsageRunRow" DiskUsageSummaryRow: description: One top-level disk usage category. type: object properties: type: type: string description: Category name, such as runs or logs. count: type: integer format: int64 description: Number of items in the category. active: type: ["integer", "null"] format: int64 description: Number of active items when applicable. size_bytes: type: integer format: int64 description: Total bytes used by the category. reclaimable_bytes: type: ["integer", "null"] format: int64 description: Bytes reclaimable by pruning the category. DiskUsageRunRow: description: Per-run disk usage information. type: object properties: run_id: type: string description: Run identifier. workflow_name: type: string description: Workflow display name. status: type: string description: Current run status. start_time: type: string description: Human-readable start timestamp. size_bytes: type: integer format: int64 description: Size used by the run scratch directory. reclaimable: type: boolean description: Whether the run is inactive and reclaimable. PruneRunsRequest: description: Filters for system run pruning. type: object properties: dry_run: type: boolean description: Preview matching runs without deleting them. default: true before: type: string description: Include runs started before this YYYY-MM-DD prefix. workflow: type: string description: Filter by workflow name substring. labels: type: object additionalProperties: type: string description: Label filters applied with AND semantics. orphans: type: boolean description: Include orphan run directories without run metadata. default: false older_than: type: string description: Include only runs older than this duration, such as 24h or 7d. PruneRunsResponse: description: Result of a prune preview or deletion. type: object properties: dry_run: type: boolean description: Whether this response is a dry-run preview. runs: type: ["array", "null"] description: Matched runs when dry-run is enabled. items: $ref: "#/components/schemas/PruneRunEntry" total_count: type: integer format: int64 description: Count of runs matching the prune filters. total_size_bytes: type: integer format: int64 description: Total bytes of the matching runs. deleted_count: type: integer format: int64 description: Number of runs deleted when dry-run is false. freed_bytes: type: integer format: int64 description: Estimated freed bytes when deletion occurs. PruneRunEntry: description: One run matched by a prune preview. type: object properties: run_id: type: string description: Run identifier. dir_name: type: string description: Scratch directory name for the run. workflow_name: type: string description: Workflow display name. size_bytes: type: integer format: int64 description: Bytes used by the run scratch directory. # ── Discovery Schemas ──────────────────────────────────────────────── RootResponseUrls: description: Collection of API discovery URLs. type: object required: - openapi_url - current_user_url - health_url properties: openapi_url: type: string description: URL of the OpenAPI JSON specification. example: /api/v1/openapi.json current_user_url: type: string description: URL of the current user endpoint. example: /api/v1/user health_url: type: string description: URL of the health check endpoint. example: /health RootResponse: description: API discovery response with navigation URLs. type: object required: - urls properties: urls: $ref: "#/components/schemas/RootResponseUrls" HealthResponse: description: Service health check response. type: object required: - status properties: status: type: string description: Health status indicator. example: ok SecretType: description: The way a secret is consumed by the sandbox. type: string enum: - environment - file - credential CreateSecretRequest: description: Request to store or update a secret. type: object required: - name - value - type properties: name: type: string description: Secret name or destination path for file secrets. value: type: string description: The secret value to store. type: $ref: "#/components/schemas/SecretType" description: type: string description: Optional operator-facing description of the secret. DeleteSecretRequest: description: Request to delete a secret by name. type: object required: - name properties: name: type: string description: Secret name or destination path for file secrets. SecretMetadata: description: Metadata for a stored secret (value is never exposed). type: object required: - name - type - created_at - updated_at properties: name: type: string description: Secret key name or destination path. example: ANTHROPIC_API_KEY type: $ref: "#/components/schemas/SecretType" description: type: string description: Optional operator-facing description of the secret. created_at: type: string format: date-time description: When the secret was first stored. updated_at: type: string format: date-time description: When the secret was last updated. SecretListResponse: description: List of stored secret metadata. type: object required: - data properties: data: type: array items: $ref: "#/components/schemas/SecretMetadata" RepoCheckResponse: description: Repository access check result. type: object required: - owner - name - accessible properties: owner: type: string description: GitHub repository owner. example: acme-corp name: type: string description: GitHub repository name. example: my-app accessible: type: boolean description: Whether the server has read-write access to this repository. default_branch: type: ["string", "null"] description: Default branch name, if accessible. example: main private: type: ["boolean", "null"] description: Whether the repository is private, if accessible. permissions: type: ["object", "null"] description: Detected permission levels. properties: pull: type: boolean push: type: boolean admin: type: boolean install_url: type: ["string", "null"] description: GitHub App installation URL when the repo is not yet accessible. DiagnosticsReport: description: Server health diagnostics report. type: object required: - version - sections properties: version: type: string description: Server version. sections: type: array items: $ref: "#/components/schemas/DiagnosticsSection" DiagnosticsSection: type: object required: - title - checks properties: title: type: string checks: type: array items: $ref: "#/components/schemas/DiagnosticsCheck" DiagnosticsCheck: type: object required: - name - status - summary properties: name: type: string status: type: string enum: - pass - warning - error summary: type: string details: type: array items: $ref: "#/components/schemas/DiagnosticsDetail" remediation: type: ["string", "null"] DiagnosticsDetail: type: object required: - text - warn properties: text: type: string warn: type: boolean UserResponse: description: Information about the authenticated user. type: object required: - login properties: login: type: string description: User's login identifier (e.g. GitHub username). example: octocat