The daemon serves a JSON HTTP API on 127.0.0.1:4748 (configurable). Authentication: none. The API is loopback-only. UIs and integrations talk to this.
{"ok": true, "port": 4748}{
"sessionId": "f3a8c2…",
"taskId": "t-f3a8c2-1748906412",
"taskGoal": "add refund flow to orders service",
"role": "developer",
"activeProvider": "claude",
"tokensUsed": 74200,
"graphNodes": 342,
"handoffsDone": 2,
"hfsScore": 0.94,
"hfsHistory": [0.40, 0.50, …],
"fsmState": "RUNNING"
}Live runtime status per provider (active/standby/exhausted/error).
Full metadata + install/auth capability flags + probe result.
Body:
{
"name": "claude",
"enabled": true,
"declaredCap": 40000,
"model": "qwen2.5-coder:32b",
"baseUrl": "http://localhost:11434"
}Patches [providers.<name>] in relay.toml and reloads.
Spawns a terminal running the per-OS install command.
Spawns the provider's OAuth subcommand (e.g. claude login).
Writes key to .relay/.env, reloads daemon env.
Multiple logins per provider (account-aware handoff). Each account is a label plus an isolated config dir; the adapter is pointed at the active account's dir.
Switch the active account for a provider. The next session (or handoff) uses it.
Register a login. configDir optional, defaults to an isolated per-label dir.
Remove a login.
Spawns a terminal running the provider's login flow against that account's config dir.
Accounts are returned inside GET /api/config/providers as accounts: [{label, active, configDir}] + activeAccount.
Scan for AI coding agents already running on this machine (process scan + on-disk transcript stores). Default window 24h.
[
{
"id": "claude_6d569909",
"provider": "claude",
"displayName": "Claude Code",
"surface": "cli",
"pid": 14032,
"running": true,
"workDir": "C:/dev/my-project",
"account": "personal",
"detectedVia": ["process", "transcript"],
"lastActive": 1752666000,
"session": {
"sessionId": "6d569909…",
"model": "claude-sonnet-5",
"initialPrompt": "add a refund flow…",
"plan": ["…"],
"tasksRemaining": ["…"],
"filesTouched": ["orders/refund.go"],
"skills": ["backend-patterns"],
"mcps": ["github"],
"recentTurns": [{"role": "user", "text": "…"}, {"role": "assistant", "text": "…"}],
"tokensIn": 84210,
"tokensOut": 12045,
"messageCount": 37
}
}
]recentTurns carries a redacted, verbatim tail of the conversation (last 16 user/assistant turns, oldest first), so a handoff moves real recent context rather than only the first and last prompts.
Lift a detected session's intent into a continuation brief (persisted under .relay/adopted/), targeting provider target. Two mutually exclusive continue modes:
"interactive": trueopens the target provider's own CLI in a new terminal, in the adopted project directory, under the active account, seeded with a prompt that reads the full brief. Relay then steps back and the developer drives the session. The response includesopened(bool) and, on failure,openError."start": true(headless) launches a Relay-orchestrated session that continues the work and streams events to the dashboard. The response includesstartedand, on failure,startError.
With neither flag, the brief is rendered and persisted but nothing is launched.
Per provider+account: remaining quota, reset time, live burn rate, and forecast ETA (feeds predictive handoff).
[
{
"provider": "claude",
"account": "personal",
"remaining": 12400,
"total": 40000,
"fractionUsed": 0.69,
"resetsAt": "2026-07-16T21:00:00Z",
"source": "transcript",
"burnPerMin": 310.5,
"etaMinutes": 39.9
}
]Multi-agent DAGs: one provider+task per node, explicit dependsOn ordering, fallback providers on failure, verify acceptance commands (verifier gate) per node.
[
{
"name": "feature",
"nodes": [
{
"id": "build",
"provider": "claude",
"task": "implement the endpoint",
"dependsOn": [],
"fallback": ["codex"],
"verify": ["go build ./...", "go test ./..."]
}
]
}
]Saves the full pipeline list (same shape as GET response). Persisted to .relay/pipelines.json.
Executes the pipeline's nodes in dependency order. Honours the single-session guard: errors with "session already running" if one is active.
The handoff timeline, read from the audit log.
[
{"seq": 3, "ts": "2026-07-16T09:41:03Z", "event": "handoff", "provider": "claude", "summary": "quota breach → codex"}
]Snapshot commits on the session branch: [{sha, short, subject, when}].
The diff for one snapshot commit.
Non-destructive rewind: creates a new branch at the snapshot so current work is never lost.
[
{
"name": "backend",
"chain": ["claude", "codex"],
"kinds": ["api", "service"],
"skills": ["go", "ts"],
"contextHint": "production backend services"
}
]{
"name": "backend",
"chain": ["claude", "codex"],
"kinds": ["api", "service"],
"skills": ["go", "ts"],
"contextHint": "production backend services",
"delete": false
}Upserts (or deletes when "delete": true).
Starts a session in the running daemon. Single-session: 409 if one is already active.
Trigger immediate handoff.
Toggle agent execution (cooperative; honoured at event boundaries).
Send a stdin reply to the active adapter (if it implements StdinReplier).
{
"summary": " orders/refund.go | 42 +++\n orders/routes.go | 18 +-",
"diff": "diff --git a/orders/refund.go …"
}Returns git diff main...relay/<sid> against the user's main branch.
{
"sessionUsd": 0.0042,
"tokensIn": 1820,
"tokensOut": 411,
"provider": "claude"
}Pending requests waiting for user resolution.
[
{
"id": "abc123",
"action": "write 250 lines to orders/refund.go",
"reason": "exceeds 200-line threshold",
"severity": "warn",
"createdAt": "2026-06-03T15:41:03Z"
}
]Resolve a pending request.
Pull events newer than the given ID:
[
{"id": 412, "ts": "09:41:27", "tag": "quota", "msg": "claude: 74% used"},
{"id": 413, "ts": "09:41:28", "tag": "tool_use", "msg": "Edit orders/routes.go"}
]Tag values: tool_use, tool_result, text, system, quota, handoff, waiting, error.
WebSocket push of the same events as they happen. Reduces latency from 1500ms (poll) to ~50ms.
{"nodes": 342, "edges": 418}
Full node + edge list (~200 most recent). Includes module and symbol nodes from the codebase scan plus session-specific decision, constraint, file, do_not_redo nodes from agent activity.
One-shot codegraph scan of an arbitrary repo path (no session needed): returns {nodes, edges} of module / symbol nodes. Used by the desktop Graph page's project picker.
FTS5 full-text search over indexed code chunks. Default limit 20.
[
{
"ID": "chunk:orders/refund.go:1-40",
"Path": "orders/refund.go",
"Lang": "go",
"StartLine": 1,
"EndLine": 40,
"Body": "package orders\n\nimport ...\n\nfunc (s *RefundService) execute(...) error {\n ...\n}",
"SHA": "a3f8c2d4",
"Dim": 0
}
]Used by the MCP relay_retrieve tool. Chunks are populated by the codegraph scanner at session start; future embedding-based ranking will use the embedding blob column.
The current continuation contract as JSON.
Discovered CLAUDE.md / AGENTS.md / Cursor rules + profile skills.
See Vision fallback.
Installed models + curated vision pull list.
Stream-pulls a model from ollama.com. Progress emitted to event log.
Spawns ollama launch <tool> --model <model> in a new terminal.
Per-provider circuit breaker snapshots.
[
{"name": "claude", "state": "closed", "failures": 0},
{"name": "codex", "state": "open", "failures": 3, "openedAt": "..."},
{"name": "ollama", "state": "half-open", "failures": 0}
]Profile success aggregates.
[
{
"profile": "backend",
"runs": 12,
"successes": 10,
"successRate": 0.833,
"avgTokens": 18420,
"avgCostUsd": 0.087,
"lastRun": "2026-06-03T15:41:03Z"
}
]Counts of secrets scrubbed this session.
{"summary": "openai_key:2, env_secret_pair:1"}