Skip to content

API Reference

Archon exposes a REST API via a Hono server with OpenAPI spec generation. All endpoints are prefixed with /api/.

By default, the API server runs at:

http://localhost:3090/api/

Override the port with the PORT environment variable or let Archon auto-allocate when running inside a worktree (range 3190-4089).

A machine-readable OpenAPI 3.0 spec is available at:

GET /api/openapi.json

You can feed this into tools like Swagger UI or use it to generate typed API clients.

None. Archon is a single-developer tool — there is no authentication on the API by default. If you expose Archon on a network, use a reverse proxy or firewall to restrict access.


MethodPathDescription
GET/healthBasic health check
GET/api/healthAPI-level health check
Terminal window
curl http://localhost:3090/health
# {"status":"ok"}
curl http://localhost:3090/api/health
# {"status":"ok","adapter":"...","concurrency":{...},"runningWorkflows":0}

MethodPathDescription
GET/api/conversationsList conversations
GET/api/conversations/{id}Get a single conversation
POST/api/conversationsCreate a new conversation
PATCH/api/conversations/{id}Update a conversation (rename)
DELETE/api/conversations/{id}Soft-delete a conversation
GET/api/conversations/{id}/messagesList messages in a conversation
POST/api/conversations/{id}/messageSend a message to a conversation
Terminal window
curl http://localhost:3090/api/conversations

Query parameters:

  • codebase_id (optional) — Filter by codebase
  • include_deleted (optional) — Include soft-deleted conversations
Terminal window
curl -X POST http://localhost:3090/api/conversations \
-H "Content-Type: application/json" \
-d '{}'

Optionally specify a codebase:

Terminal window
curl -X POST http://localhost:3090/api/conversations \
-H "Content-Type: application/json" \
-d '{"codebase_id": "your-codebase-id"}'

Returns the created conversation with its platform_conversation_id.

Terminal window
curl -X POST http://localhost:3090/api/conversations/{id}/message \
-H "Content-Type: application/json" \
-d '{"message": "What does this codebase do?"}'

The message is dispatched to the orchestrator asynchronously. The response confirms dispatch — actual AI responses arrive via SSE streaming or can be polled via the messages endpoint.

Terminal window
curl http://localhost:3090/api/conversations/{id}/messages

Query parameters:

  • limit (optional) — Number of messages to return
  • before (optional) — Cursor for pagination
Terminal window
curl -X PATCH http://localhost:3090/api/conversations/{id} \
-H "Content-Type: application/json" \
-d '{"title": "My feature discussion"}'
Terminal window
curl -X DELETE http://localhost:3090/api/conversations/{id}

Performs a soft delete — the conversation is hidden but not destroyed.


MethodPathDescription
GET/api/codebasesList registered codebases
GET/api/codebases/{id}Get a single codebase
POST/api/codebasesRegister a codebase (clone or local path)
DELETE/api/codebases/{id}Delete a codebase and clean up resources
GET/api/codebases/{id}/environmentsList isolation environments for a codebase
Terminal window
curl http://localhost:3090/api/codebases

Clone from a URL:

Terminal window
curl -X POST http://localhost:3090/api/codebases \
-H "Content-Type: application/json" \
-d '{"url": "https://github.com/user/repo"}'

Register a local path:

Terminal window
curl -X POST http://localhost:3090/api/codebases \
-H "Content-Type: application/json" \
-d '{"path": "/home/user/projects/my-repo"}'
Terminal window
curl -X DELETE http://localhost:3090/api/codebases/{id}

Removes the codebase registration and cleans up associated worktrees and isolation environments.

Terminal window
curl http://localhost:3090/api/codebases/{id}/environments

Returns the isolation environments (worktrees) associated with a codebase.


MethodPathDescription
GET/api/workflowsList available workflows
GET/api/workflows/{name}Get a single workflow definition
POST/api/workflows/validateValidate a workflow definition (in-memory, no save)
PUT/api/workflows/{name}Save (create or update) a workflow
DELETE/api/workflows/{name}Delete a user-defined workflow
Terminal window
curl http://localhost:3090/api/workflows

Query parameters:

  • cwd (optional) — Working directory to discover project-specific workflows

When cwd is omitted, Archon returns bundled default workflows and any from ~/.archon/workflows/ (home-scoped). Project-specific workflows require either the cwd query param or a registered codebase, so the endpoint is useful on first launch before any project is registered.

Returns { workflows: [...], errors?: [...] }. The errors array contains any YAML parsing failures encountered during discovery.

Terminal window
curl http://localhost:3090/api/workflows/archon-assist

Query parameters:

  • cwd (optional) — Working directory for project-specific lookup

Returns { workflow, filename, source: "project" | "global" | "bundled" }. The endpoint auto-discovers across all three scopes in order (project → home-scoped → bundled). source: "global" is returned when the workflow comes from ~/.archon/workflows/.

Terminal window
curl -X POST http://localhost:3090/api/workflows/validate \
-H "Content-Type: application/json" \
-d '{"definition": {"name": "my-wf", "description": "Test", "nodes": [{"id": "a", "prompt": "hello"}]}}'

Returns { valid: true } or { valid: false, errors: ["..."] }. Does not save anything.

Terminal window
curl -X PUT http://localhost:3090/api/workflows/my-workflow \
-H "Content-Type: application/json" \
-d '{"definition": {"name": "my-workflow", "description": "My custom workflow", "nodes": [{"id": "plan", "prompt": "Plan the feature"}]}}'

Query parameters:

  • cwd (optional) — Target directory (must have .archon/workflows/)
  • source (optional, enum: project | global) — Scope to write the workflow to. Defaults to project (writes to <cwd>/.archon/workflows/). Pass source=global to write to the home-scoped location (~/.archon/workflows/). Returns 400 "Invalid workflow source" if any other value is supplied.

Validates the definition before saving. Returns the saved workflow.

Terminal window
curl -X DELETE http://localhost:3090/api/workflows/my-workflow

Query parameters:

  • cwd (optional) — Target directory (must have .archon/workflows/)
  • source (optional, enum: project | global) — Scope to delete from. Defaults to project. Pass source=global to delete from ~/.archon/workflows/. Returns 400 "Invalid workflow source" if any other value is supplied.

Only user-defined workflows can be deleted. Bundled defaults cannot be removed.

MethodPathDescription
POST/api/workflows/{name}/runRun a workflow (JSON or multipart)
GET/api/workflows/runsList workflow runs
GET/api/workflows/runs/{runId}Get run details with events
GET/api/runs/{runId}/artifactsList artifact files produced by a run
GET/api/workflows/runs/by-worker/{platformId}Look up a run by worker conversation ID
POST/api/workflows/runs/{runId}/cancelCancel a running workflow
POST/api/workflows/runs/{runId}/resumeResume a failed workflow
POST/api/workflows/runs/{runId}/abandonAbandon a run (running, paused, or failed)
POST/api/workflows/runs/{runId}/approveApprove a paused workflow
POST/api/workflows/runs/{runId}/rejectReject a paused workflow
DELETE/api/workflows/runs/{runId}Delete a terminal run and its events
Terminal window
# JSON (no attachments)
curl -X POST http://localhost:3090/api/workflows/archon-assist/run \
-H "Content-Type: application/json" \
-d '{"message": "Explain the auth module", "conversationId": "conv-123"}'
# multipart (with file attachments — max 5 files, ≤10 MB each)
curl -X POST http://localhost:3090/api/workflows/archon-assist/run \
-F "conversationId=conv-123" \
-F "message=Investigate this trace" \
-F "files=@stacktrace.txt" \
-F "files=@screenshot.png"
Terminal window
curl http://localhost:3090/api/runs/{runId}/artifacts

Walks the run’s on-disk artifact directory (dotfiles skipped) and returns { files: [{ path, size, modifiedAt }] }. Used by the console UI’s Artifacts tab. Returns { files: [] } when the run has no codebase or the codebase name is not in owner/repo form; 400 on invalid run id or path-escape attempt, 404 if the run does not exist.

Terminal window
curl -X POST http://localhost:3090/api/workflows/runs/{runId}/resume

Resumes the workflow from where it left off, skipping already-completed nodes. Equivalent to archon workflow resume <run-id> from the CLI. Plain archon workflow run <name> invocations never resume implicitly.

Terminal window
# Approve (optionally with a comment)
curl -X POST http://localhost:3090/api/workflows/runs/{runId}/approve \
-H "Content-Type: application/json" \
-d '{"comment": "Looks good, proceed"}'
# Reject (optionally with a reason)
curl -X POST http://localhost:3090/api/workflows/runs/{runId}/reject \
-H "Content-Type: application/json" \
-d '{"reason": "Please add error handling first"}'

MethodPathDescription
GET/api/commandsList available command names
Terminal window
curl http://localhost:3090/api/commands

Query parameters:

  • cwd (optional) — Working directory for project-specific commands

Returns { commands: [{ name, source: "bundled" | "project" }] }.


MethodPathDescription
GET/api/dashboard/runsList enriched workflow runs for the dashboard

Query parameters include status filters, date ranges, and pagination. Used by the Command Center UI.


MethodPathDescription
GET/api/configGet read-only configuration (safe subset)
PATCH/api/config/assistantsUpdate the default assistant and per-provider model defaults
PATCH/api/config/tiersUpdate model-tier presets (small/medium/large)
PATCH/api/config/aliasesUpdate @custom model aliases (per-key merge; null unsets)
GET/api/providers/pi/modelsPi’s model catalog (cost/reasoning metadata; best-effort, [] on failure)

GET /api/config returns the safe config subset, now including the configured tiers, the built-in tierDefaults for the current default provider (what an unset tier resolves to), and the configured aliases.

These config routes are ungated — they write non-secret model config to ~/.archon/config.yaml and work on solo installs (no TOKEN_ENCRYPTION_KEY required). Contrast with the AI Provider Credentials routes below, which require an identity.

Terminal window
# Read current config (includes `tiers` + `tierDefaults`)
curl http://localhost:3090/api/config
# Set the default assistant
curl -X PATCH http://localhost:3090/api/config/assistants \
-H "Content-Type: application/json" \
-d '{"assistant": "claude"}'
# Or update per-provider model defaults
curl -X PATCH http://localhost:3090/api/config/assistants \
-H "Content-Type: application/json" \
-d '{"assistants": {"claude": {"model": "opus"}}}'
# Set a model tier (a `null` tier value unsets it, falling back to the built-in default)
curl -X PATCH http://localhost:3090/api/config/tiers \
-H "Content-Type: application/json" \
-d '{"tiers": {"large": {"provider": "claude", "model": "opus"}}}'
# Set a @custom alias (a `null` value unsets it)
curl -X PATCH http://localhost:3090/api/config/aliases \
-H "Content-Type: application/json" \
-d '{"aliases": {"@fast": {"provider": "claude", "model": "haiku"}}}'

Each user can override the install-wide model config with personal tiers, @custom aliases, and a default assistant — the highest-precedence resolver layer, applied to runs and chats they start. These routes require a resolved web identity (X-Archon-User header or a Better Auth session) but no TOKEN_ENCRYPTION_KEY — model names aren’t secrets. Without an identity they return 401, and model resolution stays config-only (solo installs are unchanged).

MethodPathDescription
GET/api/auth/me/ai-prefsThe current user’s stored prefs (raw layer, not merged)
PATCH/api/auth/me/ai-prefs/tiersUpdate personal tier presets (per-key merge; null unsets)
PATCH/api/auth/me/ai-prefs/aliasesUpdate personal @custom aliases (per-key merge; null unsets)
PATCH/api/auth/me/ai-prefs/defaultSet (or clear with null) the personal default assistant
Terminal window
# Point YOUR `large` tier at opus without touching the install config
curl -X PATCH http://localhost:3090/api/auth/me/ai-prefs/tiers \
-H "X-Archon-User: your-user-id" \
-H "Content-Type: application/json" \
-d '{"tiers": {"large": {"provider": "claude", "model": "opus"}}}'

All writes validate the provider (registered), effort (provider vocabulary), and alias names (@ prefix, not a reserved tier keyword), and return the updated prefs. The console exposes the same scopes as the “This install / Just me” toggle on AI Settings; the CLI as archon ai … --scope user.


Per-user provider credentials let each user bill their runs and chats to their own API key or subscription instead of the shared install key. These endpoints require a resolved web identity (X-Archon-User header or a Better Auth session) — GET /api/auth/providers returns 401 without one. The encryption key is auto-provisioned on every install; TOKEN_ENCRYPTION_KEY is an optional override for managed deployments.

MethodPathDescription
GET/api/auth/providersList the current user’s connected credentials (metadata only)
PUT/api/auth/providers/{provider}Connect (upsert) an API key for a provider
DELETE/api/auth/providers/{provider}Disconnect a provider credential (idempotent)
POST/api/auth/providers/{provider}/oauth/startBegin a subscription (OAuth) login
POST/api/auth/providers/{provider}/oauth/pollPoll a subscription login session

Credentials are encrypted at rest; no endpoint ever returns a secret value — responses carry only provider/kind/label metadata.

Terminal window
curl http://localhost:3090/api/auth/providers \
-H "X-Archon-User: your-user-id"

Returns { enabled, connections: [{ provider, kind, label }], available, subscriptionAvailable, agents }:

  • available — every vendor id you can connect an API key for (anthropic, openai, github-copilot, plus the Pi backends). Legacy claude/codex/copilot ids are accepted on writes and normalized.
  • subscriptionAvailable — the subset that supports subscription (OAuth) login: anthropic, openai, and github-copilot. (The ChatGPT/Codex subscription runs an Archon-owned PKCE flow that captures the id_token the Codex CLI requires — see #1924.)
  • agents — the agent -> credential matrix: per registered agent { id, displayName, catalog: 'static'|'dynamic', ready, credentials: [{ vendor, displayName, kinds, connected, subscriptionAvailable, installEnv, ambientConfigured? }] }. installEnv/ambientConfigured report server-side detection so readiness renders on solo installs too; OpenCode is catalog:'dynamic' (introspect via GET /api/providers/opencode/credentials).
Terminal window
curl -X PUT http://localhost:3090/api/auth/providers/openrouter \
-H "X-Archon-User: your-user-id" \
-H "Content-Type: application/json" \
-d '{"apiKey": "sk-...", "label": "personal"}'

Returns { success, provider, kind: "api_key", label }. An unknown provider or a blank key returns 400.

Terminal window
curl -X DELETE http://localhost:3090/api/auth/providers/openrouter \
-H "X-Archon-User: your-user-id"

Idempotent — disconnecting a provider that was never connected still returns { success: true }.

Subscription login is a two-step start -> poll flow held server-side. start returns a mode:

  • manual (anthropic, Claude Pro/Max) — show the returned url; the user authorizes in a browser and pastes the resulting code back via poll.
  • device (github-copilot) — show userCode + verificationUri; poll until connected.
Terminal window
# 1. Start a login session
curl -X POST http://localhost:3090/api/auth/providers/anthropic/oauth/start \
-H "X-Archon-User: your-user-id"
# {"sessionId":"...","mode":"manual","url":"https://...","expiresIn":600}
# 2. Poll (pass the pasted `code` once, for manual flows)
curl -X POST http://localhost:3090/api/auth/providers/anthropic/oauth/poll \
-H "X-Archon-User: your-user-id" \
-H "Content-Type: application/json" \
-d '{"sessionId": "...", "code": "the-pasted-code"}'
# {"status":"connected"}

poll returns { status: "pending" | "connected" | "error", detail? }. A provider that does not support subscription login returns 400 on start.

The CLI equivalent of this whole surface is archon ai. For the end-to-end setup walkthrough, see Per-user credentials and AI Settings.


MethodPathDescription
GET/api/update-checkCheck for available updates (binary builds only)

Returns { updateAvailable, currentVersion, latestVersion, releaseUrl }. For non-binary (source) builds, always returns updateAvailable: false without making external requests.


PathDescription
/api/stream/{conversationId}Real-time events for a conversation
/api/stream/__dashboard__Multiplexed workflow events across all conversations

These are Server-Sent Events (SSE) endpoints — connect with EventSource in a browser or any SSE client.

Terminal window
# Listen to a conversation stream
curl -N http://localhost:3090/api/stream/your-conversation-id

Events are JSON-encoded with a type field. See the Web UI documentation for the full list of event types.


Terminal window
# 1. Create a conversation
CONV_ID=$(curl -s -X POST http://localhost:3090/api/conversations \
-H "Content-Type: application/json" \
-d '{}' | jq -r '.platform_conversation_id')
# 2. Send a message
curl -X POST http://localhost:3090/api/conversations/$CONV_ID/message \
-H "Content-Type: application/json" \
-d '{"message": "/status"}'
# 3. Poll for messages
curl http://localhost:3090/api/conversations/$CONV_ID/messages
Terminal window
# 1. Create a conversation scoped to a codebase
CONV_ID=$(curl -s -X POST http://localhost:3090/api/conversations \
-H "Content-Type: application/json" \
-d '{"codebase_id": "your-codebase-id"}' | jq -r '.platform_conversation_id')
# 2. Start the workflow
curl -X POST http://localhost:3090/api/workflows/archon-assist/run \
-H "Content-Type: application/json" \
-d "{\"message\": \"How does auth work?\", \"conversationId\": \"$CONV_ID\"}"
# 3. Monitor via SSE
curl -N http://localhost:3090/api/stream/$CONV_ID