How do I run jobs and autonomous work?
http://localhost:3001 Jobs are the unit of autonomous work in Daemion. Each job is an extension record (type job) paired with a prompt.md on disk. You can trigger any job on demand, inspect past runs, and review improvement proposals that agents generate through the autoresearch system.
How do I trigger a job?
Trigger a job by name. Returns immediately with a thread ID. The job runs in the background — stream its output via WebSocket.
| Parameter | Type | Description |
|---|---|---|
job REQUIRED | string (path) | The name of the job extension to run, e.g. daily-digest. |
dry | boolean (query) | If true, run in dry-run mode — the job executes but skips any destructive actions. |
Trigger a job
curl -X POST “http://localhost:3001/run/daily-digest”
-H “Authorization: Bearer $DAEMION_TOKEN”
Dry run — skip destructive side effects
curl -X POST “http://localhost:3001/run/daily-digest?dry=true”
-H “Authorization: Bearer $DAEMION_TOKEN”
The response is 202 Accepted. The job is running in the background:
{ “job”: “daily-digest”, “dry”: false, “threadId”: “thr_01abc123”, “status”: “started” }
Open a WebSocket subscription on threadId to receive streaming events as the job executes. See the WebSocket events reference for event shapes.
How does thread routing work?
If the job’s extension definition has an owner_agent_id, the job’s output is routed into that agent’s most recent active thread (creating one if none exists). Standalone jobs get their own dedicated thread, reused across runs.
How do I inspect job run history?
List past runs for a named job. Returns runs in reverse-chronological order.
| Parameter | Type | Description |
|---|---|---|
name REQUIRED | string (path) | The job extension name. |
limit | number (query) | Maximum number of runs to return. Defaults to 20. |
Last 20 runs
curl “http://localhost:3001/jobs/daily-digest/runs”
-H “Authorization: Bearer $DAEMION_TOKEN”
Last 5 runs
curl “http://localhost:3001/jobs/daily-digest/runs?limit=5”
-H “Authorization: Bearer $DAEMION_TOKEN”
How do I see what an agent has been doing?
Recent thread activity for a specific agent. Returns turns across all of the agent's threads, newest first. Content snippets are truncated to 150 characters.
| Parameter | Type | Description |
|---|---|---|
name REQUIRED | string (path) | The agent extension ID. |
limit | number (query) | Maximum number of activity rows to return. Defaults to 20. |
curl “http://localhost:3001/agents/opus/activity”
-H “Authorization: Bearer $DAEMION_TOKEN”
curl “http://localhost:3001/agents/opus/activity?limit=50”
-H “Authorization: Bearer $DAEMION_TOKEN”
Returns 404 {"error": "agent not found"} if no extension of type agent exists with that ID.
How do I read the daily briefing?
A structured summary of recent agent activity, pending work, and system state. Cached and stale-while-revalidate — the first request generates it synchronously, subsequent requests serve from cache.
| Parameter | Type | Description |
|---|---|---|
project_id | string (query) | Scope the briefing to a specific project. Omit to get a global briefing across all projects. |
Global briefing
curl “http://localhost:3001/briefing”
-H “Authorization: Bearer $DAEMION_TOKEN”
Project-scoped briefing
curl “http://localhost:3001/briefing?project_id=my-project”
-H “Authorization: Bearer $DAEMION_TOKEN”
The response includes a stale boolean. When stale: true, the cached value was served and a fresh briefing is regenerating in the background — poll again shortly to get the updated version.
How do I review autoresearch proposals?
Autoresearch is Daemion’s self-improvement loop. Agents generate proposals — patches to their own prompts, soul files, or job configs — and stage them for your review. These endpoints let you list, read, approve, and reject those proposals.
List pending proposals
List all pending improvement proposals staged by agents.
curl “http://localhost:3001/proposals”
-H “Authorization: Bearer $DAEMION_TOKEN”
Each entry in the array includes the proposal’s agent, date, title, and type.
Read a proposal
Read the full content of a proposal. Both :agent and :date must be alphanumeric with hyphens or underscores — path traversal is rejected.
| Parameter | Type | Description |
|---|---|---|
agent REQUIRED | string (path) | The agent name that generated the proposal. |
date REQUIRED | string (path) | The date segment of the proposal path, e.g. 2026-03-31. |
name | string (path, optional) | For nested proposals: /proposals/:agent/:date/:name — an additional segment identifying the specific proposal. |
Top-level proposal
curl “http://localhost:3001/proposals/opus/2026-03-31”
-H “Authorization: Bearer $DAEMION_TOKEN”
Nested proposal
curl “http://localhost:3001/proposals/opus/2026-03-31/improve-context”
-H “Authorization: Bearer $DAEMION_TOKEN”
Apply (approve) a proposal
Apply a staged proposal. Writes the proposal content to its target file, re-syncs extensions, and records the outcome as an experiment. Optionally accepts edited content in the body.
| Parameter | Type | Description |
|---|---|---|
content | string (body, optional) | Edited proposal content. If provided, applies your version instead of the original staged file. |
Apply as-is
curl -X POST “http://localhost:3001/proposals/opus/2026-03-31/apply”
-H “Authorization: Bearer $DAEMION_TOKEN”
Apply with edits
curl -X POST “http://localhost:3001/proposals/opus/2026-03-31/apply”
-H “Authorization: Bearer $DAEMION_TOKEN”
-H “Content-Type: application/json”
-d ’{“content”: ”# Edited system prompt content…”}’
Returns 200 {"status": "applied"} on success. After applying, the extension registry is resynced — the change takes effect immediately without a gateway restart.
Reject a proposal
Reject a staged proposal and record the reason. The proposal file is marked rejected and logged as a discard experiment.
| Parameter | Type | Description |
|---|---|---|
reason | string (body, optional) | Human-readable explanation of why the proposal was rejected. Stored in the experiment log. |
curl -X POST “http://localhost:3001/proposals/opus/2026-03-31/reject”
-H “Authorization: Bearer $DAEMION_TOKEN”
-H “Content-Type: application/json”
-d ’{“reason”: “Prompt change too aggressive — reverting to original tone.”}’
Returns 200 {"status": "rejected"} on success.
How do I interact with the autoresearch system directly?
These endpoints expose the underlying experiment tracking and iteration engine that powers autoresearch.
List experiments
List recorded experiments — the trial-and-error history of autoresearch iterations.
| Parameter | Type | Description |
|---|---|---|
domain | string (query) | Filter to a specific domain, e.g. agent:opus. |
verdict | string (query) | Filter by verdict: keep, discard, or crash. |
limit | number (query) | Maximum number of experiments to return. |
All experiments for the opus agent domain
curl “http://localhost:3001/autoresearch/experiments?domain=agent:opus”
-H “Authorization: Bearer $DAEMION_TOKEN”
Only kept experiments
curl “http://localhost:3001/autoresearch/experiments?domain=agent:opus&verdict=keep”
-H “Authorization: Bearer $DAEMION_TOKEN”
Get a single experiment
Fetch the full record for a single experiment by ID.
curl “http://localhost:3001/autoresearch/experiments/exp_07xyz456”
-H “Authorization: Bearer $DAEMION_TOKEN”
Check domain confidence
Calculate the MAD-based confidence score for a domain and metric. Returns the current confidence value and a consecutive-discard count (a signal to stop iterating).
| Parameter | Type | Description |
|---|---|---|
domain REQUIRED | string (query) | The domain to score, e.g. agent:opus. Required. |
metric | string (query) | The metric name to score against. Defaults to quality. |
curl “http://localhost:3001/autoresearch/confidence?domain=agent:opus&metric=quality”
-H “Authorization: Bearer $DAEMION_TOKEN”
{ “domain”: “agent:opus”, “metric”: “quality”, “confidence”: { “confidence”: 0.87, “sampleSize”: 12, “mad”: 0.04 }, “consecutiveDiscards”: 1 }
A confidence value of 9999 means the variance is effectively zero (Infinity capped for JSON serialization).
Trigger an autoresearch iteration
Manually trigger one autoresearch iteration for a domain. Validated against DomainConfigSchema. All path fields must be within the user's home directory. Returns 202 immediately — the iteration runs in the background.
| Parameter | Type | Description |
|---|---|---|
domain REQUIRED | string | Domain identifier, e.g. agent:opus. |
asset_path REQUIRED | string | Absolute path to the asset being improved (e.g. a system prompt file). Must be within home directory. |
benchmark_path | string | Path to the benchmark script or file. |
checks_path | string | Path to a checks/test file. |
rubric_path | string | Path to a scoring rubric. |
curl -X POST http://localhost:3001/autoresearch/run
-H “Authorization: Bearer $DAEMION_TOKEN”
-H “Content-Type: application/json”
-d ’{
“domain”: “agent:opus”,
“asset_path”: “/Users/me/.daemion/agents/opus/system.md”,
“rubric_path”: “/Users/me/.daemion/agents/opus/rubric.md”
}’
{ “status”: “started”, “iterationId”: “iter-1711872000000”, “domain”: “agent:opus” }
How do I read the Pulse briefing?
Editorial summary for the Pulse hero panel. Combines pending proposal counts, signal anomalies from the last 24 hours, and the latest self-reflect job output into a single prose summary.
curl “http://localhost:3001/pulse/briefing”
-H “Authorization: Bearer $DAEMION_TOKEN”
{ “prose”: “2 improvements staged for review: Sharper context instructions (prompt for opus). Cost spike: opus at 2.3x average.”, “highlights”: [“Cost spike: opus at 2.3x average”], “proposalCount”: 2, “selfReflectAvailable”: false }
The prose field is ready to render directly. If the self-reflect job has run recently, prose contains the agent’s own reflection output (up to 1000 characters). highlights lists signal anomalies detected in the last 24 hours — cost spikes and agents that haven’t used Engram.
Frequently asked questions
POST /run/:job fires a job immediately, on demand, regardless of its schedule. Both create a thread and stream events via WebSocket.threadId returned by POST /run/:job is the WebSocket channel. Connect before or immediately after triggering the job and you'll receive text-delta, tool-start, tool-end, and finish events as the job runs.agent:<name> for agent prompt improvements. The domain groups experiments together so confidence and consecutive-discard counts are computed per-domain.seedBuiltInExtensions and syncDiskExtensions to reload the extension registry, and refreshes the skill context if available. The change is live immediately — no gateway restart required.stale field in the response to know whether you're seeing cached data.What can go wrong
404 {"error": "agent not found"} — GET /agents/:name/activity — no extension of type agent exists with that ID. Use GET /extensions?type=agent to list valid agent IDs.
400 {"error": "invalid path segment"} — Proposal paths :agent and :date must match [a-zA-Z0-9][a-zA-Z0-9_-]*. Path traversal sequences (.., /, etc.) are rejected.
404 {"error": "proposal not found"} — The proposal file doesn’t exist at the expected path under ~/.daemion/autoresearch/proposals/. Check GET /proposals for the correct agent/date combination.
400 {"error": "failed to reject proposal"} — The proposal file exists but could not be marked rejected. Verify the gateway process has write access to ~/.daemion/autoresearch/proposals/.
400 {"error": "invalid domain config", "details": ...} — POST /autoresearch/run — the body failed DomainConfigSchema validation. The details object shows which fields failed.
400 {"error": "path must be within home directory: ..."} — All path fields in POST /autoresearch/run must resolve to paths inside the user’s home directory. Absolute paths to system directories or other users’ home directories are rejected.
400 {"error": "domain parameter required"} — GET /autoresearch/confidence requires a domain query parameter.
Job output missing from WebSocket — If you connect to the WebSocket after the job finishes, you will not receive the events that already fired. Connect to the thread ID immediately after receiving the 202 response.
What’s next?
- WebSocket events — subscribe to real-time job and agent output
- Extensions API — create and manage job extensions
- Conversations API — send messages to agents and read thread history