HTTP API Reference

Full reference for the Fathom REST API. Manage autonomous worker sessions, stream events, and operate coworkers, schedules, memory, governance and computer use programmatically.

Overview

The Fathom API is a RESTful control plane for universal autonomous workers. It manages sessions, persistent coworkers, scheduled operations, memory, governance, computer use and notifications; research is one supported workflow. All responses are JSON-encoded. Streaming endpoints use Server-Sent Events (SSE).

The API supports two authentication methods via HTTP headers:

HTTP Headers
Authorization: Bearer <your-api-key>
X-Api-Key: <your-api-key>

Authentication

When FATHOM_API_KEYS is configured, API requests under /api/v1 require a matching Bearer token or X-Api-Key header. With no keys configured, loopback deployments allow open access; binding the server to a non-loopback address requires configuring keys.

Environment
FATHOM_API_KEYS=key-abc123,key-def456,key-ghi789

Each key maps to an independent identity. Rate limiting is applied per-key: 120 requests/minute for standard endpoints. Exceeding limits returns 429 Too Many Requests.

⚠

Security note: Never expose API keys in client-side code or public repositories. Use environment variables or a secrets manager.

Endpoints

POST/api/v1/sessions

Create a new worker session. The API spawns a coordinator that orchestrates sub-agents for the supplied task; research is one possible workflow.

Request Body

JSONRequest
{
"query": "Find SaaS companies in Berlin with 10-50 employees",
"output_dir": "session-001"
}
ParameterTypeDescription
querystringResearch query or task description
output_dirstringDirectory to store results (optional)

Response — 202 Accepted

JSONResponse
{
"id": "sess_a1b2c3d4",
"status": "running",
"query": "Find SaaS companies in Berlin...",
"output_dir": "./results/session-001"
}
GET/api/v1/sessions

List all research sessions. Returns an array sorted by creation date (newest first).

Response — 200 OK

JSONResponse
{
"sessions": [
  {
    "id": "sess_a1b2c3d4",
    "query": "Find SaaS companies in Berlin...",
    "status": "completed",
    "output_dir": "./results/session-001",
    "total_tokens": 42000,
    "total_agents": 3,
    "created_at": "2026-08-07T10:30:00Z",
    "updated_at": "2026-08-07T10:35:00Z",
    "active": false
  },
  {
    "id": "sess_e5f6g7h8",
    "query": "Analyze competitor pricing...",
    "status": "running",
    "output_dir": "./results/session-002",
    "total_tokens": 18000,
    "total_agents": 2,
    "created_at": "2026-08-07T11:00:00Z",
    "updated_at": "2026-08-07T11:02:00Z",
    "active": true
  }
],
"count": 2
}
GET/api/v1/sessions/:id

Retrieve detailed status of a specific session, including all spawned agents and their current states.

Path Parameters

ParameterTypeDescription
idstringSession identifier (e.g., sess_a1b2c3d4)

Response — 200 OK

JSONResponse
{
"id": "sess_a1b2c3d4",
"query": "Find SaaS companies in Berlin...",
"status": "running",
"output_dir": "./results/session-001",
"total_tokens": 42000,
"total_agents": 3,
"created_at": "2026-08-07T10:30:00Z",
"updated_at": "2026-08-07T10:31:00Z",
"active": true
}
DELETE/api/v1/sessions/:id

Cancel a running session. All active agents are terminated gracefully.

Response — 200 OK

JSONResponse
{
"id": "sess_a1b2c3d4",
"status": "cancelled"
}
POST/api/v1/sessions/:id/steer

Send a mid-run instruction to adjust the research direction without stopping the session.

Request Body

JSONRequest
{
"message": "Focus only on companies with Series A funding"
}

Response — 202 Accepted

JSONResponse
{
"id": "sess_a1b2c3d4",
"steered": true,
"message": "Instruction delivered to session sess_a1b2c3d4"
}
GET/api/v1/sessions/:id/results

Retrieve completed research results for a session. Returns 409 if the session is not completed.

Response — 200 OK

JSONResponse
{
"session_id": "sess_a1b2c3d4",
"status": "completed",
"summary": "Found 3 SaaS companies in Berlin matching criteria.",
"output_dir": "./results/session-001",
"total_tokens": 42000,
"total_agents": 3,
"findings": [
  {
    "file": "./results/session-001/techcorp.md",
    "content": "TechCorp GmbH — B2B SaaS, 25 employees, Series A 2025"
  }
]
}
GET/api/v1/ws

Multiplexed bidirectional WebSocket connection for live agent streaming, control frame dispatch, and session telemetry. Supports token authentication via ?api_key= query parameter.

JavaScriptClient
const ws = new WebSocket('ws://localhost:8080/api/v1/ws?api_key=sk-fathom-...');
ws.onmessage = (event) => console.log(JSON.parse(event.data));
POST/api/v1/webhooks/inbound

Inbound webhook reactor for GitHub, Sentry, Stripe, and CRM triggers. Verified using HMAC-SHA256 via X-Fathom-Signature or X-Hub-Signature-256.

JSONRequest
{
"source": "github",
"event_type": "issues.opened",
"payload": { "issue": { "number": 42, "title": "Memory leak in agent" } }
}
GET/api/v1/openapi.json

Download the complete OpenAPI 3.1 schema defining all available endpoints, request bodies, and response structures.

GET/api/v1/sessions/:id/events

Open an SSE stream for real-time events from a specific session. Events are sent as data: lines with a JSON payload containing a type field (snake_case). There is no event: field in the SSE frame.

Response — 200 OK (text/event-stream)

SSEStream
data: {"type":"agent_spawned","agent_id":"agent_x1y2z3","role":"web-researcher"}

data: {"type":"finding","agent_id":"agent_x1y2z3","title":"TechCorp GmbH","confidence":0.92}

data: {"type":"session_completed","session_id":"sess_a1b2c3d4"}
GET/api/v1/events

Global SSE stream. Receives events from all active sessions. Useful for dashboards and monitoring.

Query Parameters

ParameterTypeDescription
typesstringComma-separated event types to filter (optional)
GET/api/v1/agents

List all active and recently completed agents across all sessions.

Response — 200 OK

JSONResponse
{
"agents": [
  {
    "id": "agent_x1y2z3",
    "session_id": "sess_a1b2c3d4",
    "task": "Research web presence of SaaS companies",
    "status": "completed",
    "depth": 0,
    "tokens_used": 18420
  }
],
"count": 1
}
GET/api/v1/agents/:id

Get detailed status and metadata for a specific agent, including tool calls and LLM interaction log.

Response — 200 OK

JSONResponse
{
"id": "agent_x1y2z3",
"session_id": "sess_a1b2c3d4",
"parent_id": null,
"task": "Research web presence of SaaS companies",
"role": "web-researcher",
"depth": 0,
"status": "completed",
"tokens_used": 18420,
"created_at": "2026-08-07T10:30:01Z",
"completed_at": "2026-08-07T10:30:42Z"
}
POST/api/v1/sessions/:id/answer

Answer a pending question tool call. The agent blocks until the operator responds or timeout expires.

Request Body

JSON
{"request_id": "ctrl_abc123", "text": "Focus on Series B companies"}

Response — 200 OK

JSON
{"answered": true, "request_id": "ctrl_abc123"}

Returns 410 GONE if agent stopped waiting, 404 if no such request_id.

POST/api/v1/sessions/:id/approve

Allow or deny a pending side-effect tool call (e.g. save_contacts, git_push).

Request Body

JSON
{"request_id": "ctrl_def456", "approved": true}

Response — 200 OK

JSON
{"approved": true, "request_id": "ctrl_def456"}
POST/api/v1/jobs

Submit a durable background job. Spawns a fully detached runner process.

Request Body

JSON
{"task": "Find CTOs at fintech startups in Berlin", "attempts": 3}

Response — 202 ACCEPTED

JSON
{"id": "job_abc123", "status": "queued", "task": "...", "attempts": 3, "max_attempts": 3, "output_dir": "./jobs/job_abc123", "log": "./jobs/job_abc123/run.log"}
GET/api/v1/jobs

List all jobs. Jobs with running status but dead PID are marked “stale”.

Response — 200 OK

JSON
{"jobs": [...], "count": 5}
GET/api/v1/jobs/:id

Get job status by full ID or unique prefix.

Response — 200 OK

JSON
{"id": "job_abc123", "status": "completed", "task": "...", "attempts": 1, "max_attempts": 3}
DELETE/api/v1/jobs/:id

Cancel an active job. Terminates the runner process and marks the job cancelled.

Response — 200 OK

JSON
{"id": "job_abc123", "status": "cancelled"}
GET/api/v1/jobs/:id/log

Tail the job log file.

Query Parameters

HTTP
?lines=100  (default 100, cap 2000)

Response — 200 OK

JSON
{"lines": ["...", "..."], "total_lines": 150, "returned": 100}
POST/api/v1/jobs/:id/rerun

Re-run a finished or stale job. Resets state and spawns a new runner.

Response — 202 ACCEPTED

JSON
{"id": "job_abc123", "status": "queued", ...}
GET/api/v1/memories

List memories or perform hybrid search. If ?q= is non-empty, does semantic search.

Query Parameters

HTTP
?q=CTO+fintech&scope=agent&status=active&limit=20&top_k=10

Response — 200 OK

JSON
{"query": "CTO fintech", "memories": [...]}
POST/api/v1/memories/absorb

Absorb facts through the full memory pipeline (classification, embedding, dedup, storage).

Request Body

JSON
{"facts": [{"content": "Acme Corp uses React", "confidence": 0.9}], "source": "research", "scope": "agent"}

Response — 200 OK

JSON
{"created": 1, "duplicates": 0, "superseded": 0}
GET/api/v1/memories/stats

Memory store statistics: scope counts, entity graph nodes/edges.

Response — 200 OK

JSON
{"embedding_model": "text-embedding-3-small", "scopes": {"agent": {"active": 42, "superseded": 5, "archived": 12}}, "entity_graph": {"nodes": 28, "edges": 45}}
POST/api/v1/memories/distill

Promote run-scoped facts into agent-scoped knowledge.

Query Parameters

HTTP
?session=sess_abc123&dry_run=true

Response — 200 OK

JSON
{"promoted": 8, "archived": 3}
POST/api/v1/memories/gc

Garbage-collect expired/stale facts and compact groups.

Query Parameters

HTTP
?ttl_days=30&dry_run=false

Response — 200 OK

JSON
{"stale_archived": 15, "compacted": 2, "dry_run": false}
GET/api/v1/memories/:id

Get one memory by ID with optional history following.

Query Parameters

HTTP
?follow=latest  (options: active, latest, full_history)

Response — 200 OK

JSON
{"memories": [...]}
DELETE/api/v1/memories/:id

Soft-delete a memory by setting status to “archived”.

Response — 200 OK

JSON
{"archived": "mem_abc123"}
GET/health

Health check endpoint. No authentication required. Returns server status and version.

Response — 200 OK

JSONResponse
{
"status": "ok",
"service": "fathom",
"version": "0.3.0",
"database": "ok",
"active_sessions": 2
}

// Possible values:
// status: "ok" | "degraded"
// database: "ok" | "error"
GET/metrics

Prometheus-compatible metrics endpoint. No authentication required. Scrape with any Prometheus-compatible collector.

Response — 200 OK (text/plain)

PrometheusMetrics
# HELP pr_sessions_total Total number of sessions
# TYPE pr_sessions_total counter
pr_sessions_total 42

# HELP pr_agents_active Currently active agents
# TYPE pr_agents_active gauge
pr_agents_active 3

# HELP pr_request_duration_seconds Request latency
# TYPE pr_request_duration_seconds histogram
pr_request_duration_seconds_bucket{le="0.1"} 120
GET/dashboard

Embedded single-file HTML dashboard. Sessions, agent tree, memory stats, jobs, and live SSE event feed. The page itself is public, while its API data requests use the configured API key when authentication is enabled.

Response — 200 OK

text/html — self-contained dashboard page. Open in a browser.

SSE Event Types

Server-Sent Events are pushed over persistent HTTP connections. Each event is sent as a data: line with a JSON payload. Event types use snake_case in the JSON type field (e.g., session_started, agent_spawned). There is no event: field in the SSE frame.

Event TypeDescription
session_startedFired when a new session is initialized
agent_spawnedA new agent was created within the session
agent_state_changedAgent transitioned between states (idle → running → completed)
findingAn agent discovered a research finding
tool_call_startedAgent began executing a tool (web search, scrape, etc.)
tool_call_completedTool execution finished with results
llm_stream_chunkStreaming token from the LLM response (for live UI)
agent_completedAgent finished its task successfully
agent_failedAgent encountered an unrecoverable error
session_completedAll agents finished; session results are ready
session_failedSession terminated due to a critical error
question_askedAgent’s question tool is waiting for operator answer (use POST /answer)
approval_requestedAgent wants to run a side-effect tool that needs approval (use POST /approve)
session_forkedSession was forked from another session
file_change_undoneA file change was rolled back via undo
title_generatedSession title was auto-generated

Governance, collaboration & computer relay

Current servers may expose governance decisions, coworker/channel state, AG-UI events, and computer relay controls under the same authenticated /api/v1 prefix.

RouteDescription
GET /api/v1/governance/policyRead the active governance policy.
PUT /api/v1/governance/policyReplace the governance policy.
POST /api/v1/governance/decideEvaluate a governed action.
GET /api/v1/governance/auditRead governance audit events.
GET|POST /api/v1/coworkersList or create coworker records.
GET|POST /api/v1/channelsList or create collaboration channels.
GET /api/v1/ag-ui/eventsStream AG-UI events.
GET /api/v1/computers/healthCheck the default computer relay.
POST /api/v1/computers/navigateNavigate the default computer relay.
POST /api/v1/computers/click|type|keyControl the default computer relay.

Coworkers, channels & schedules

These authenticated routes persist worker identity and recurring operations. Request bodies are validated by the server; consult the root docs/HTTP-API.md for field-level contracts.

RouteDescription
GET|POST /api/v1/coworkersList or create persistent coworker profiles.
GET|PUT|PATCH|DELETE /api/v1/coworkers/:idInspect or update a coworker. There is no separate coworker run route.
GET /api/v1/channels?coworker_id=…List channels for a coworker; the query parameter is required.
POST /api/v1/channelsCreate a channel linked to a coworker and optionally a session.
PUT|PATCH|DELETE /api/v1/channels/:idUpdate or delete a channel.
GET|POST /api/v1/schedulesList or create cron-like schedules with a coworker, query, timezone and enabled flag.
GET|PUT|PATCH|DELETE /api/v1/schedules/:idInspect, update or delete a schedule.
POST /api/v1/schedules/claimAtomically claim due schedules for a bounded scheduler tick.

Credentials vault

Credentials are encrypted at rest with the key configured by FATHOM_CREDENTIAL_KEY. Plaintext secrets are accepted only when storing and are never returned by list or create responses.

RouteDescription
GET /api/v1/credentialsList metadata: id, name, kind and timestamps.
POST /api/v1/credentialsStore a credential with the fields name, kind and secret.
DELETE /api/v1/credentials/:idDelete a stored credential; secrets cannot be retrieved through the API.

Replay, observability & notifications

RouteDescription
GET /api/v1/replayList redacted governed actions; optional session, agent and bounded limit filters.
GET /api/v1/observability/summaryRead live counters and bounded governance audit counts.
POST /api/v1/notifications/testTest one configured symbolic channel: webhook, email or telegram. The request accepts only a channel field.

Computer-use relay

Computer routes proxy to the configured service (default loopback URL via FATHOM_COMPUTER_SERVICE_URL). Browser actions use POST routes such as /computers/navigate, while health, snapshots, screenshots and tabs use GET; supervised agent routes additionally require COMPUTER_TOKEN.

RouteDescription
POST /api/v1/computers/sessionStart or refresh a computer session.
GET /api/v1/computers/health|snapshot|screenshot|tabsInspect computer health, accessibility snapshot, screenshot or open tabs.
POST /api/v1/computers/navigate|click|type|key|secretPerform browser actions; secret avoids returning or logging the value.
POST /api/v1/computers/control/take|releaseHand control to or from an operator.
GET|DELETE /api/v1/computers/filesList or delete files in the confined workspace.
GET /api/v1/computers/files/read · PUT /api/v1/computers/files/writeRead or write a confined workspace file; DELETE /api/v1/computers/files removes one.
GET|POST /api/v1/computers/:agent_id/…Agent-scoped relay routes are available when a supervised computer is configured with COMPUTER_TOKEN.

CLI Commands

The fathom CLI provides local development and operational tools. Available on servers provisioned for you — request access at [email protected].

CommandDescription
fathom runExecute a one-shot research query and print results to stdout
fathom tuiLaunch the interactive terminal UI for monitoring sessions
fathom serveStart the HTTP API server (this API)
fathom contactsManage contact lists for outreach campaigns
fathom resumeResume a previously interrupted session from checkpoint
fathom configView and manage configuration (API keys, model settings, etc.)
fathom memorySearch and maintain semantic memory
fathom sessionsBrowse stored sessions
fathom profilesList, show, or create profiles
fathom jobsSubmit and manage background jobs
fathom benchBenchmark tool execution without network or LLM calls
fathom statsShow tool-call statistics for a recorded session

Error Codes

All error responses follow a consistent JSON format with a human-readable error string.

JSONError Format
{
"error": "Invalid or missing API key"
}
StatusCodeDescription
400bad_requestInvalid or missing required parameters
401unauthorizedMissing or invalid API key in request headers
404not_foundThe requested resource (session, agent) does not exist
429rate_limitedToo many requests — retry after the Retry-After header
500internal_errorUnexpected server error — check logs for details
503service_unavailableLLM API key not configured or memory subsystem disabled
409conflictThe resource is in a state that doesn’t allow the operation (e.g. session is not running)
410goneThe agent stopped waiting for a response (approval/question timed out)