Skip to content

HTTP endpoints (v5.0.0)

Domain-agnostic remote-call, storage, and search API for machinable.

A generic substrate for driving machinable.Interface subclasses remotely: transport (JSON control plane + binary data plane), a config/identity index with search, and an Execution lifecycle. Each interface (a Python module in the project) decides what bytes and method calls mean while machinable stays use-case-agnostic.

Conceptual model

  • Interface: a materialized data node (config + identity). InterfaceInfo carries no lifecycle status.
  • Execution: the only run-record with lifecycle (is_active, timestamps).
  • Project: the unit a request binds to. Multiple projects (and Python interpreters) are served from one gateway.

Discovering the full contract

  • REST: this OpenAPI document (/openapi.json, /docs).
  • WebSocket protocol (connect / call / stream / chunk upload / chunk read / event): GET /v1/protocol returns a machine-readable description, since OpenAPI cannot model WebSocket frames.

Request routing (headers; query equivalents in parentheses)

  • X-Machinable-Project (?project=): target project, must be under the server's allowlist; defaults to the launch project.
  • X-Machinable-User (X-Machinable-User): attributes created interfaces (created_by); defaults to the server OS user.
  • X-Machinable-Python (?python=): interpreter; a non-gateway interpreter is routed to a subprocess worker.
  • Authorization: Bearer <token>: required when the server sets api_token (/docs and /openapi.json are exempt).

Capability map

remote_call, binary_upload, binary_read, config_search, create_by_id, mutable_label, creator_attribution, multi_project; see /v1/protocol for the surfaces that expose each.

REST endpoints

interfaces

Create/attach interfaces, invoke methods, search by config, set the mutable label, read files, and the WebSocket data plane.

GET /v1/interfaces

List Interfaces

Responses:

POST /v1/interfaces

Create Interface

Create (materialize) an interface, optionally with a client-supplied id.

Idempotent in uuid: creating again with the same id returns the existing instance unchanged (content-addressed dedupe).

Request body: CreateInterfaceRequest (required)

Responses:

POST /v1/interfaces/search

Search

Generic config search over interface instances (operators, sort, paging).

Request body: FindRequest (required)

Responses:

POST /v1/interfaces/resolve

Resolve

Dry-run a compact version → resolved config + CLI, without materializing.

Request body: ResolveRequest (required)

Responses:

POST /v1/interfaces/lifecycle

Lifecycle

Content-addressed compute lifecycle for a config.

One of: draft / running / cached / failed.

Request body: LifecycleRequest (required)

Responses:

POST /v1/interfaces/call

Call Interface

Request body: InterfaceCallRequest (required)

Responses:

GET /v1/interfaces/{uuid}

Get Interface

ParameterInRequiredDescription
uuid (string)pathyes

Responses:

DELETE /v1/interfaces/{uuid}

Delete Interface

ParameterInRequiredDescription
uuid (string)pathyes

Responses:

PATCH /v1/interfaces/{uuid}/label

Set Interface Label

Set/replace an interface's mutable label (FCFS / last-write-wins).

ParameterInRequiredDescription
uuid (string)pathyes

Request body: SetLabelRequest (required)

Responses:

GET /v1/interfaces/{uuid}/executions

List Interface Executions

ParameterInRequiredDescription
uuid (string)pathyes
activequeryno
limit (integer)queryno

Responses:

GET /v1/interfaces/{uuid}/provenance

Get Provenance

The provenance graph: how this interface came to be.

Recipe (config/context/derivation) plus history (executions, each with the Manifest it used), as a normalized node-link DAG. depth bounds the walk; rels (comma-separated edge labels, e.g. derivation,runs,manifest) overrides the default policy.

ParameterInRequiredDescription
uuid (string)pathyes
depth (integer)queryno
relsqueryno

Responses:

GET /v1/interfaces/{uuid}/data

Get Data Status

Whether the run's stored data is readable now (local / remote / evicted).

ParameterInRequiredDescription
uuid (string)pathyes

Responses:

Get Related

The interface's lineage neighbours (derived, uses, executions, …).

ParameterInRequiredDescription
uuid (string)pathyes

Responses:

POST /v1/interfaces/{uuid}/archive

Archive Interface

Soft-archive (hide) an interface, or restore it with ?restore=true.

ParameterInRequiredDescription
uuid (string)pathyes
restore (boolean)queryno

Responses:

GET /v1/interfaces/{uuid}/files

List Files

ParameterInRequiredDescription
uuid (string)pathyes

Responses:

GET /v1/interfaces/{uuid}/files/{path}

Read File

ParameterInRequiredDescription
uuid (string)pathyes
path (string)pathyes

Responses:

executions

Dispatch runs and query Execution lifecycle status and output.

GET /v1/executions

List All Executions

ParameterInRequiredDescription
activequeryno
incompletequeryno
parentqueryno
limit (integer)queryno

Responses:

POST /v1/executions

Dispatch Execution

Dispatch interfaces into an Execution, each under its context stack.

Mirrors the CLI element chain (machinable get … --launch): for each interface, the context interfaces are entered in order (and exited in reverse) so their predicates fold into the interface's identity at materialization; the interfaces are added to the Execution container, which is then dispatched. Project is the request's ambient project.

Request body: DispatchRequest (required)

Responses:

GET /v1/executions/{uuid}

Get Execution

ParameterInRequiredDescription
uuid (string)pathyes

Responses:

GET /v1/executions/{uuid}/output

Get Execution Output

ParameterInRequiredDescription
uuid (string)pathyes

Responses:

POST /v1/executions/{uuid}/cancel

Cancel Execution

Best-effort cancel: write a cancelled marker into the run's directory.

A live dispatch's watcher polls for it and injects ExecutionInterrupted; a not-yet- started or already-finished run simply carries the marker (a no-op). No execution- engine coupling.

ParameterInRequiredDescription
uuid (string)pathyes

Responses:

project

Discover Interface modules and reflect their Config schemas.

GET /v1/project

List Project Modules

Responses:

GET /v1/project/remotes

Get Remotes

Shareable interfaces the project resolves by URL (slurm, globus, …).

Responses:

GET /v1/project/{module}/widget/{asset}

Get Widget Asset

Serve a widget's ES module or stylesheet (module-level assets).

ParameterInRequiredDescription
module (string)pathyes
asset (string)pathyes

Responses:

GET /v1/project/{module}

Get Module Schema

ParameterInRequiredDescription
module (string)pathyes

Responses:

GET /v1/projects

List Open Projects

List the projects the server can serve.

The default, any with live state, the allowlist roots, and any process-isolated workers currently running.

Responses:

  • 200 Successful Response → object

source

Read/write/create/rename/delete interface source files (opt-in, token-gated; confined to the project base directory).

GET /v1/source

List Source

List the editable source files under the project base directory.

Responses:

GET /v1/source/{path}

Read Source

Read a file's content; the strong ETag (MD5) is also a response header.

ParameterInRequiredDescription
path (string)pathyes

Responses:

PUT /v1/source/{path}

Write Source

Create or fully overwrite a file.

Conditional writes: If-Match: "&lt;etag>" (or *) returns 412 on a stale ETag; If-None-Match: * returns 412 if the file already exists (create-only). Editing invalidates caches made stale by the change.

ParameterInRequiredDescription
path (string)pathyes

Request body: SourceWriteRequest (required)

Responses:

DELETE /v1/source/{path}

Delete Source

Delete a source file and invalidate caches made stale by its removal.

ParameterInRequiredDescription
path (string)pathyes

Responses:

POST /v1/source/move

Move Source

Atomically rename/move a file within the base directory.

Handles interface renames, including converting a single-file module to a package layout (foo.pyfoo/__init__.py) and back.

Request body: SourceMoveRequest (required)

Responses:

meta

Self-description: the WebSocket protocol, interface hooks, and capability map that OpenAPI cannot express.

GET /v1/protocol

Describe the WebSocket protocol and capability map

Return the non-OpenAPI half of the contract.

Includes every WebSocket frame type, the binary upload/read sequences, the interface hooks a project implements (read, emit, callable methods), cross-cutting request headers, and the capability map.

Responses:

health

Server status, version, and active execution count.

GET /v1/health

Health

Responses:

MIT Licensed