Skip to content

REST API Reference

The viz dashboard server (ari vizari-core/ari/viz/server.py) exposes a JSON HTTP API used by the bundled web UI and accessible to external integrations. Endpoints are dispatched by viz/routes.py into per-domain handler modules (viz/api_*.py, viz/checkpoint_api.py, viz/file_api.py, etc., split out in Phase 3B).

All endpoints are unauthenticated by default — ari viz binds to 127.0.0.1 and is intended for the local user. Wrap it in nginx / oauth2-proxy if you want to expose it.

Conventions

  • Base URL: http://127.0.0.1:<port> (default port set by ari viz).
  • All response bodies are JSON unless noted otherwise.
  • Errors come back as {"error": "<message>"} with a non-2xx HTTP code.
  • CORS preflight (OPTIONS) is permissive on /api/*.

Typed contracts (stable endpoints)

The highest-traffic GET endpoints have their response shape mirrored by a frontend TypeScript type in ari-core/ari/viz/frontend/src/types/index.ts and guarded by ari-core/tests/test_api_schema_contract.py (asserts the always-present keys as a subset — extra/optional fields are allowed, so the contract is additive). Verified 2026-05-30.

EndpointProducerFrontend typeAlways-present keys
GET /stateroutes.py /state builderAppStaterunning_pid, is_running, exit_code, running, pid, status_label (the rest are checkpoint-gated → optional in the type). cost is the parsed cost_summary.json object (CostSummary), not a number.
GET /api/settingsapi_settings._api_get_settingsSettingsthe full defaults dict (llm_model, llm_provider, ollama_host, temperature, … , nested ors); arbitrary saved keys also pass through ({**defaults, **saved}).
GET /api/checkpointscheckpoint_api._api_checkpointsCheckpoint[]id, path, status, node_count, review_score, best_metric (always null), mtime; best_scientific_score is conditional.
GET /api/checkpoint/<id>/summarycheckpoint_api._api_checkpoint_summaryCheckpointSummaryid, path (or {error:"not found"}); all report bodies are conditional. reproducibility_report is a parsed object (legacy runs: string), not always a string.

Contracts are permissive: new optional fields may be added without breaking consumers; existing fields are never removed during a migration (see the refactoring global rules).

Worked examples

Minimal curl request/response pairs for the endpoints you reach for first. The examples assume the dashboard is on the default port 8765.

Read the live state:

bash
curl http://localhost:8765/state
json
{
  "phase": "bfts",
  "nodes": { "total": 7, "completed": 5, "running": 2, "failed": 0 },
  "model": { "provider": "ollama", "model": "qwen3:8b" },
  "cost": { "usd": 0.0, "tokens": 0 }
}

Launch a run:

bash
curl -X POST http://localhost:8765/api/launch \
  -H 'Content-Type: application/json' \
  -d '{"experiment_md": "# Goal\nImprove GFLOP/s of a dense matmul.\n",
       "profile": "laptop", "provider": "ollama", "model": "qwen3:8b",
       "max_nodes": 8, "max_depth": 3, "workers": 2}'
json
{ "ok": true, "pid": 48213, "checkpoint_path": "workspace/checkpoints/20260526T101500_matmul" }

List checkpoints:

bash
curl http://localhost:8765/api/checkpoints
json
[
  { "id": "20260526T101500_matmul", "status": "running", "nodes": 7, "review_score": null },
  { "id": "20260520T090000_sort",   "status": "done",    "nodes": 12, "review_score": 0.71 }
]

Error shape (any endpoint, non-2xx):

json
{ "error": "no active checkpoint" }

State + dashboards

MethodPathPurposeSource
GET/stateCurrent BFTS state snapshot used by the dashboard live viewroutes.py:211
GET/api/gpu-monitorGPU utilisation pollroutes.py:654
GET/api/resource-metricsCPU / memory / disk metricsroutes.py:886
GET/api/logsRecent log lines for the active runroutes.py:903

Models + skills

MethodPathPurpose
GET/api/modelsDiscover LLMs available via LiteLLM + Ollama
GET/api/ollama-resourcesMemory / disk needed by a model
GET/api/ollama/<...>Proxy through to a local Ollama daemon
GET/api/skillsEnumerate registered skills + their tool counts
GET/api/skill/<skill_name>Per-skill metadata (tool list, env vars)
GET/api/toolsCombined tool catalogue across all skills
GET/api/scheduler/detectlocal / slurm / apptainer autodetect
GET/api/slurm/partitionsSLURM partition list
GET/api/container/infoContainer runtime probe
GET/api/container/imagesCached SIF / OCI images
POST/api/container/pullPull / build an image referenced by ARI_CONTAINER_IMAGE

Checkpoint browsing

MethodPathPurpose
GET/api/checkpointsList all checkpoints under ARI_CHECKPOINT_DIR parent
GET/api/checkpoint/<id>/summaryRun summary (goal, node count, status, top metric)
GET/api/checkpoint/<id>/memoryLetta memory contents
GET/api/checkpoint/<id>/memory_accessMemory write/read telemetry
GET/api/checkpoint/<id>/filesFile list with sizes + types
GET/api/checkpoint/<id>/file?path=...Raw file content (text or base64)
GET/api/checkpoint/<id>/file/rawSame, alternate route
GET/api/checkpoint/<id>/filetreeHierarchical tree view
GET/api/checkpoint/<id>/filecontentMulti-file batch read
GET/api/active-checkpointCurrently selected checkpoint
POST/api/switch-checkpointChange the active checkpoint
POST/api/delete-checkpointDelete a checkpoint (also drops the matching Letta agent)
POST/api/checkpoint/file/saveEdit a file in-place
POST/api/checkpoint/file/deleteDelete a file from a checkpoint
POST/api/checkpoint/compileRun pdflatex on a paper draft

Run lifecycle

MethodPathPurpose
POST/api/launchStart a new BFTS run (ari run programmatically)
POST/api/run-stageRun a single pipeline stage
POST/api/stopStop the active run

Sub-experiments + lineage

MethodPathPurpose
GET/api/sub-experimentsAll sub-experiment records
GET/api/sub-experiments/<run_id>Single sub-experiment detail
POST/api/sub-experiments/launchLaunch a child run inheriting from a parent checkpoint
GET/api/lineage-decisions/<run_id>Decisions emitted by the stagnation rule (v0.7.0)

Memory backend

MethodPathPurpose
GET/api/memory/healthLetta health probe
GET/api/memory/detectInventory of running Letta deploy paths
POST/api/memory/start-localSpawn a local Letta server
POST/api/memory/stop-localStop the local Letta server
POST/api/memory/restartRestart the local Letta server

Settings + workflow

MethodPathPurpose
GET/api/settingsRead settings.json
POST/api/settingsWrite settings.json
GET/api/profilesSaved profile list
GET/api/env-keysEnv-var keys ARI knows about (no values)
POST/api/env-keysPersist env-var key/value pairs to .env
GET/api/workflowActive workflow.yaml
GET/api/workflow/defaultBundled default
GET/api/workflow/flowWorkflow visualised as DAG nodes / edges
POST/api/workflowSave workflow.yaml
POST/api/workflow/flowSave the DAG view
POST/api/workflow/skillsToggle which skills are enabled
POST/api/workflow/disabled-toolsPer-skill tool whitelist / blacklist

Wizard / config gen

MethodPathPurpose
GET/api/experiment-detailWizard's parsed experiment.md
POST/api/config/generateGenerate ari.yaml from wizard answers
POST/api/chat-goalLLM-assisted goal narrative refinement
POST/api/ssh/testProbe an SSH cluster login

Uploads + few-shot corpus

MethodPathPurpose
POST/api/uploadMultipart upload into the active checkpoint
POST/api/upload/deleteRemove an uploaded file
GET/api/fewshot/<rubric_id>Few-shot examples for a rubric
POST/api/fewshot/<rubric_id>/syncPull the published corpus
POST/api/fewshot/<rubric_id>/uploadAdd an example
POST/api/fewshot/<rubric_id>/deleteRemove an example
GET/api/rubricsAvailable reviewer rubrics (driven by ARI_RUBRIC)

Node reports

MethodPathPurpose
GET/api/nodes/<...>/reportPer-node node_report.json

EAR + publish (v0.7.0)

MethodPathPurpose
GET/api/ear/<run_id>EAR bundle metadata for a run
GET/api/ear/<run_id>/publish-yamlGenerated publish.yaml preview
POST/api/ear/<run_id>/curateRun the curate step
POST/api/ear/<run_id>/publish-yamlSave the publish.yaml
POST/api/ear/clone-verifyVerify a remote bundle by hash
GET/api/publish/settingsBackend configuration
POST/api/publish/settingsUpdate backend configuration
GET/api/publish/<run_id>/previewPre-publish payload preview
GET/api/publish/<run_id>/recordRead publish_record.json
POST/api/publish/<run_id>/promotePromote stagedunlisted / public
POST/api/publish/<run_id>Push to the configured backend

Static + frontend

MethodPathPurpose
GET/static/<path>Bundled UI assets
GET/memory/<path>Memory inspector static page
GET/codefile?path=...Source file viewer

Updating this reference

The route table is the dispatch chain in ari-core/ari/viz/routes.py — when you add a route, mirror it here. A future improvement could auto-generate this page from the dispatch chain (the master plan suggests OpenAPI generation for the same reason).

See also

  • docs/concepts/architecture.md — viz package overview.
  • ari-core/ari/viz/__init__.py — module-level docstring with the current sub-module map.