API Reference

REST + SSE. Self-hostable. Per-request model overrides via AsyncLocalStorage. JSON-RPC 2.0 for MCP.

Auth + Tenants

Self-hosted — no API key on DelOS routes. Backend uses your .env.local for upstream providers (Groq, Mistral, Gemini, HydraDB, ElevenLabs). Pass tenantId in every body to scope memory per device / user. Same tenant ID across installs = automatic sync via HydraDB.

# .env.local
HYDRA_DB_API_KEY=...
GROQ_API_KEY=...
MISTRAL_API_KEY=...
GOOGLE_GENERATIVE_AI_API_KEY=...
ELEVENLABS_API_KEY=...                 # optional
DELRIO_TENANT_ID=default                # fallback

Endpoints

POST/api/run

Stream a full agent run (SSE). Goal → planner → executor → critic → answer.

REQUEST
{
  "goal": "What is 7×8?",
  "chaos": ["tool_flake"],            // optional
  "interrupt": { "afterSteps": 1, "newGoal": "..." },  // optional
  "maxSteps": 8,                       // optional
  "models": { "planner": "groq:openai/gpt-oss-120b" }, // optional overrides
  "mcpServers": [{ "id": "demo", "name": "...", "url": "...", "enabled": true }],
  "tenantId": "me_personal"            // optional
}
RESPONSE
SSE stream of RunEvent JSON lines (meta, phase, thought, tool_call, tool_result, recover, adapt, usage, subagent, memory_*, metric, answer, error)
CURL
curl -N -X POST http://localhost:3000/api/run \
  -H "Content-Type: application/json" \
  -d '{"goal":"What is 7×8?"}'
POST/api/cohort

Race N models on the same goal. Judge picks winner + merges.

REQUEST
{ "goal": "Why is the sky blue?", "members": ["groq:openai/gpt-oss-120b","google:gemini-2.5-flash","mistral:mistral-large-latest"], "judge": "mistral:mistral-large-latest" }
RESPONSE
SSE: cohort_start → cohort_member spawn/done/fail per member → cohort_verdict { winnerIndex, rationale, scores, merged }
POST/api/build-app

Generate a DelOS app spec from natural language. Zod-validated.

REQUEST
{ "prompt": "Build me a stopwatch with start/stop/reset.", "models": {...}, "tenantId": "..." }
RESPONSE
{ "spec": { "id": "...", "name": "...", "icon": "...", "width": 320, "height": 240, "initialState": {...}, "root": {...} } }
POST/api/voice-command

Interpret a transcript → action JSON for autonomy mode.

REQUEST
{ "transcript": "open the terminal and find the capital of japan" }
RESPONSE
{ "intent": "run_mission", "app": "terminal", "payload": "find the capital of japan", "reply": "Opening terminal and..." }
POST/api/stt

Whisper Large v3 Turbo speech-to-text. Free quota via Groq.

REQUEST
multipart/form-data: file=<audio blob>, model=whisper-large-v3-turbo, language=en (opt)
RESPONSE
{ "text": "transcript here", "ms": 1234, "model": "whisper-large-v3-turbo" }
POST/api/tts

ElevenLabs text-to-speech (premium, 10k chars/mo free).

REQUEST
{ "text": "hello world", "voiceId": "...", "stability": 0.5, "similarity": 0.75 }
RESPONSE
audio/mpeg binary · 503 when no key (client falls back to browser TTS)
GET/api/tts

Probe TTS configuration.

RESPONSE
{ "available": true, "voiceId": "...", "modelId": "..." }
GET/api/tts/voices

List available ElevenLabs voices.

RESPONSE
{ "available": true, "voices": [{ "id": "...", "name": "...", "labels": {...} }] }
POST/api/steer

Inject a live instruction into a running orchestrator.

REQUEST
{ "runId": "abc123", "instruction": "focus on dates only" }
RESPONSE
{ "ok": true } · orchestrator picks up between steps and triggers WARP zone replan
POST/api/tool

Direct single-tool invocation (used by AppRuntime).

REQUEST
{ "tool": "calc", "args": { "expr": "(2+3)*4" } }
RESPONSE
{ "ok": true, "data": { "value": 20 } }
POST/api/quick-agent

One-shot LLM reply, no tools, no critic.

REQUEST
{ "prompt": "Write a haiku about pixel art.", "tenantId": "..." }
RESPONSE
{ "text": "..." }
GET/api/memory?q=...&tenantId=...&topK=24

Recall memories from HydraDB + local fallback.

RESPONSE
{ "query": "...", "hits": [{ "text": "...", "score": 0.82 }], "local": [{ "id": "...", "text": "...", "tags": [...], "createdAt": ... }] }
POST/api/mcp/demo

Bundled MCP server. JSON-RPC 2.0. 8 tools: wiki_search · world_time · random_fact · crypto_price · exchange_rate · dictionary · dad_joke · weather.

REQUEST
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "crypto_price", "arguments": { "symbol": "btc" } } }
RESPONSE
{ "jsonrpc": "2.0", "id": 1, "result": { "content": [{ "type": "text", "text": "BTC: $77,250 (24h 0.20%)" }] } }
GET/api/tools/list

List the local tool registry with schemas.

RESPONSE
{ "tools": [{ "name": "calc", "description": "...", "tags": ["math","compute"], "fields": [...] }, ...] }
GET/api/stats

Single source of truth for site-wide counts + live drift/replan metrics.

RESPONSE
{ "features": 51, "endpoints": 21, "tools": { "local": 6, "mcp": 11, "total": 17 }, "apps": 24, "models": [...], "runs_today": 12, "avg_drift_7d": 0.07, "replans_per_run_7d": 0.4, "metrics_line": "Critic verifies every step · avg drift this week: 0.07 · replans/run: 0.4" }
GET/api/run-log?runId=...

Fetch full SSE event log for a specific run (or list recent if no runId).

RESPONSE
{ "ok": true, "run": { "runId": "...", "goal": "...", "events": [...RunEvent], "answer": "...", "drift": 0.07, "replans": 0, "success": true } }
GET/api/live

SSE stream of all run starts/events/ends across tenants (for /live dashboard).

RESPONSE
data: { "type": "snapshot|start|event|end|heartbeat", ... }
POST/api/memory/seed

Seed 12 graph-shaped sample memories under a tenant (idempotent — auto-runs on first /api/memory GET too).

REQUEST
{ "tenantId": "delrio_demo" }
RESPONSE
{ "ok": true, "seeded": 12, "entries": [...] }
POST/api/os-builder

Sub-agent fan-out mission. Spawns N parallel agents that each build an app via /api/build-app. Emits app_materialize for each spec. Ends with Doom launch.

REQUEST
{ "goal": "Build OS shell with 5 apps", "subGoals": ["Calculator...", "Clock...", ...], "tenantId": "..." }
RESPONSE
SSE: meta · phase · thought · subagent (5 spawns) · tool_result name=app_materialize (×N) · metric (agents/requests/tokens/usd) · tool_result name=launch_app · answer · done

SSE Event Schema

Every event has { t, at }. at is a Unix-ms timestamp. Consume via fetch + ReadableStream.

meta{ runId, at }

First event of a stream. Capture runId for /api/steer.

phase{ phase: 'boot'|'recall'|'plan'|'act'|'critic'|'replan'|'store'|'done'|'fail', note?, at }

Lifecycle marker.

thought{ agent: 'planner'|'executor'|'critic', text, at }

Free-form agent reasoning.

tool_call{ name, args, at }

Outbound tool invocation.

tool_result{ name, ok, result?, error?, at }

Tool returned.

recover{ reason, strategy, at }

Recovery layer fired (1-UP).

adapt{ from, to, reason, at }

Goal swap / drift correction (WARP zone).

usage{ role, model, promptTokens, completionTokens, ms, at }

LLM call telemetry.

subagent{ id, goal, status: 'spawn'|'done'|'fail', result?, at }

Parallel sub-agent fan-out.

memory_write{ key, preview, at }

HydraDB store.

memory_recall{ query, hits, at }

HydraDB recall.

metric{ key, value, at }

drift / elapsed_ms / replans / tool_calls / successes / wall_time_ms.

tool_result name=app_materialize{ ok: true, result: { spec: AppSpec }, at }

DelOS shell listens for this and spawns a window with the spec (os-builder mission).

tool_result name=launch_app{ ok: true, result: { app: string }, at }

Auto-launch a built-in DelOS app (e.g. doom).

answer{ text, at }

Final answer. Sourced from final_answer tool when planner included it; otherwise post-loop LLM synth.

error{ message, at }

Fatal.