API reference
38 routes, generated from crates/daemon/openapi/v1.json.
Every route requires a bearer token discovered from the daemon's port+token discovery file (see the getting-started guide); loopback-only, no accounts.
assertions
GET /v1/assertions
operation: list_assertions
Parameters
| name | in | required | type |
|---|---|---|---|
persona | query | yes | string (uuid) |
Response 200
AssertionDto
| field | required | type | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
claim | yes | string | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
evidence | yes | array of EvidenceView (tagged union)
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fabricated | yes | boolean | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
id | yes | string (uuid) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
persona | yes | string (uuid) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
requested_by | yes | string | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
source | yes | string (uuid) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
status | yes | string |
POST /v1/assertions/capture
operation: capture_assertion
Request body
CaptureRequest
| field | required | type |
|---|---|---|
claim | yes | string |
persona | yes | string (uuid) |
research_search_context | yes | string |
research_session | yes | string (uuid) |
source | yes | string (uuid) |
Response 200
AssertionDto
| field | required | type | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
claim | yes | string | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
evidence | yes | array of EvidenceView (tagged union)
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fabricated | yes | boolean | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
id | yes | string (uuid) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
persona | yes | string (uuid) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
requested_by | yes | string | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
source | yes | string (uuid) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
status | yes | string |
Response 400
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
GET /v1/assertions/{id}
operation: get_assertion
Parameters
| name | in | required | type |
|---|---|---|---|
id | path | yes | string (uuid) |
Response 200
AssertionDto
| field | required | type | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
claim | yes | string | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
evidence | yes | array of EvidenceView (tagged union)
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fabricated | yes | boolean | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
id | yes | string (uuid) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
persona | yes | string (uuid) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
requested_by | yes | string | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
source | yes | string (uuid) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
status | yes | string |
Response 404
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
POST /v1/assertions/{id}/attach-evidence
operation: attach_evidence
Parameters
| name | in | required | type |
|---|---|---|---|
id | path | yes | string (uuid) |
Request body
AttachEvidenceRequest
| field | required | type |
|---|---|---|
evidence | yes | evidence (object, no properties) |
Response 200
(no body)
Response 400
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
Response 404
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
POST /v1/assertions/{id}/confirm
operation: confirm_assertion
Parameters
| name | in | required | type |
|---|---|---|---|
id | path | yes | string (uuid) |
Response 200
(no body)
Response 403
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
POST /v1/assertions/{id}/mark-fabricated
Mark-as-fabricated (CR1, WP-09c): human-token-required, same pattern as `confirm_assertion`. 422 on `EngineError::Domain(TransitionError::NotAgentOrigin)` (already mapped by `problem.rs`'s existing `EngineError::Domain(_) => 422` arm — the assertion isn't AI-origin).
operation: mark_fabricated
Parameters
| name | in | required | type |
|---|---|---|---|
id | path | yes | string (uuid) |
Response 200
(no body)
Response 403
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
Response 422
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
audit
GET /v1/audit
operation: get_audit
Parameters
| name | in | required | type |
|---|---|---|---|
include | query | no | ['string', 'null'] |
limit | query | no | ['integer', 'null'] |
Response 200
AuditEntryDto
| field | required | type |
|---|---|---|
actor | yes | string |
at_ms | yes | integer (int64) |
event_type | yes | string |
id | yes | string (uuid) |
payload | no | any |
blobs
POST /v1/blobs
Raw-bytes upload (WP-06 B3): stores content-addressed, returns the address only (never a filesystem path).
operation: post_blob
Request body
anyResponse 200
BlobRefDto
| field | required | type |
|---|---|---|
blob | yes | string |
capabilities
GET /v1/capabilities
operation: get_capabilities
Response 200
CapabilitiesDto
| field | required | type |
|---|---|---|
api_version | yes | string |
ingest | yes | array of string |
conflicts
GET /v1/conflicts
operation: list_conflicts
Response 200
ConflictDto
| field | required | type |
|---|---|---|
assertions | yes | array of string (uuid) |
id | yes | string (uuid) |
open | yes | boolean |
diagnostics
GET /v1/diagnostics
operation: get_diagnostics
Response 200
DiagnosticsDto
| field | required | type |
|---|---|---|
log_location_description | yes | string |
GET /v1/diagnostics/bundle
CR8 (WP-09d spec Scope 5): human-token-only, `text/plain` (D7) — a copyable, redacted diagnostics bundle: app/api version, platform triple, capabilities, data-dir layout version, audit-entry counts by event type (counts only, never payloads), and the last 200 lines of the current rotating log file.
operation: get_diagnostics_bundle
Response 200
(no body)
events
GET /v1/events/stream
SSE change feed (D9): best-effort, no replay. A late subscriber missed prior events and catches up by re-reading state.
operation: sse_stream
Response 200
(no body)
imports
POST /v1/imports/gedcom
CR10 (WP-12): the bytes-to-`&Path` bridge. `Engine::import_gedcom` takes a filesystem path (it reads + blob-puts internally; no bytes/ `BlobRef` overload exists) — this handler writes the raw upload to a temp file under `<data_root>/scratch/` (never `/tmp`, I10 data-dir discipline), calls the op, and removes the temp file on both the success and failure paths. Write-class, standard-token auth (agent- invokable, same posture as `capture`/`add_source`).
operation: post_import_gedcom
Parameters
| name | in | required | type |
|---|---|---|---|
filename | query | no | ['string', 'null'] |
Request body
anyResponse 200
ImportSummaryDto
| field | required | type |
|---|---|---|
assertion_count | yes | integer (int32) |
dangling_pointer_count | yes | integer |
person_count | yes | integer (int32) |
persona_count | yes | integer (int32) |
raw_file | yes | string |
source_count | yes | integer (int32) |
top_level_record_counts | yes | map: string → integer (int32) |
unmapped_tag_counts | yes | map: string → integer (int32) |
Response 422
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
integrations
POST /v1/integrations/claude-desktop/connect
CR7 (WP-09d spec Scope 4): human-token-only (D2) — rewriting the user's Claude Desktop config is an outward-facing machine mutation; agent proposes, human disposes. Body is reserved/ignored (`{}`). All the merge/backup/restore logic lives in `integrations.rs` per this module's "no business logic" doc.
operation: connect_claude_desktop
Response 200
ConnectClaudeDesktopResultDto
| field | required | type |
|---|---|---|
action | yes | string |
backup_path_description | yes | string |
restart_required | yes | boolean |
Response 403
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
Response 422
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
Response 500
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
jobs
GET /v1/jobs
Job endpoints 501-with-problem-detail until WP-05c's executor lands (D6; spec's `job_endpoints_return_501_problem_until_executor_lands`).
operation: list_jobs
Response 501
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
GET /v1/jobs/{id}
operation: get_job
Parameters
| name | in | required | type |
|---|---|---|---|
id | path | yes | string (uuid) |
Response 501
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
pending
GET /v1/pending
operation: get_pending
Response 200
AssertionDto
| field | required | type | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
claim | yes | string | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
evidence | yes | array of EvidenceView (tagged union)
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fabricated | yes | boolean | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
id | yes | string (uuid) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
persona | yes | string (uuid) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
requested_by | yes | string | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
source | yes | string (uuid) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
status | yes | string |
personas
POST /v1/personas
operation: post_persona
Request body
CreatePersonaRequest
| field | required | type |
|---|---|---|
label | yes | string |
source | yes | string (uuid) |
Response 200
(no body)
GET /v1/personas/{id}
operation: get_persona
Parameters
| name | in | required | type |
|---|---|---|---|
id | path | yes | string (uuid) |
Response 200
PersonaDto
| field | required | type |
|---|---|---|
id | yes | string (uuid) |
label | yes | string |
source | yes | string (uuid) |
Response 404
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
persons
GET /v1/persons
operation: list_persons
Response 200
PersonDto
| field | required | type |
|---|---|---|
certainty | yes | string |
id | yes | string (uuid) |
GET /v1/persons/{id}
operation: get_person
Parameters
| name | in | required | type |
|---|---|---|---|
id | path | yes | string (uuid) |
Response 200
PersonDto
| field | required | type |
|---|---|---|
certainty | yes | string |
id | yes | string (uuid) |
Response 404
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
proof-arguments
POST /v1/proof-arguments
Write-class, standard-token auth like `capture` (D4) — recording a proof argument is a normal research write, not destructive/exfiltrating.
operation: post_proof_argument
Request body
RecordProofArgumentRequest
| field | required | type |
|---|---|---|
certainty | yes | certainty (object, no properties) |
claims_exhaustive_search | yes | boolean |
conclusion | yes | string |
contrary_evidence | yes | contrary_evidence (object, no properties) |
correlation_reasoning | yes | string |
question | yes | string (uuid) |
supporting | yes | array of string (uuid) |
Response 200
ProofArgumentDto
| field | required | type | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
certainty | yes | string | |||||||||
claims_exhaustive_search | yes | boolean | |||||||||
conclusion | yes | string | |||||||||
contrary_evidence | yes | array of ContraryTreatmentView
| |||||||||
correlation_reasoning | yes | string | |||||||||
id | yes | string (uuid) | |||||||||
question | yes | string (uuid) | |||||||||
supporting | yes | array of string (uuid) |
Response 400
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
Response 404
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
Response 422
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
proposals
GET /v1/proposals
operation: list_proposals
Response 200
ProposalDto
| field | required | type |
|---|---|---|
destination_hint | no | ['string', 'null'] |
id | yes | string (uuid) |
kind | yes | string |
reason | no | ['string', 'null'] |
requested_by | yes | string |
status | yes | string |
target | no | ['string', 'null'] (uuid) |
POST /v1/proposals
operation: propose
Request body
ProposeRedactRequest
| field | required | type |
|---|---|---|
reason | yes | string |
target | yes | string (uuid) |
Response 200
(no body)
POST /v1/proposals/{id}/approve
operation: approve_proposal
Parameters
| name | in | required | type |
|---|---|---|---|
id | path | yes | string (uuid) |
Request body
ApproveRequest
| field | required | type |
|---|---|---|
summary_shown | no | ['string', 'null'] |
Response 200
(no body)
Response 403
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
POST /v1/proposals/{id}/deny
operation: deny_proposal
Parameters
| name | in | required | type |
|---|---|---|---|
id | path | yes | string (uuid) |
Request body
DenyRequest
| field | required | type |
|---|---|---|
reason | yes | string |
Response 200
(no body)
Response 403
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
redactions
POST /v1/redactions
**The single atomic human-redaction request** (D8): the whole grant-then-execute sequence runs inside ONE `EngineHandle::call` closure, so it is ONE engine-thread command — no other command can be serviced between `human_grant` and `redact`. Concurrent requests for the same target: the engine thread drains its channel strictly one job at a time, so the second job to run sees the target already in `extra.redacted_targets` and gets `ApiError::AlreadyRedacted` (409) instead of minting a second tombstone (spec's `concurrent_redaction_requests_for_same_target_yield_one_tombstone`).
operation: post_redaction
Request body
RedactionRequest
| field | required | type |
|---|---|---|
reason | yes | string |
summary_shown | yes | string |
target | yes | string (uuid) |
Response 200
RedactionResultDto
| field | required | type |
|---|---|---|
blobs_purged | yes | integer |
redacted | yes | boolean |
Response 403
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
Response 409
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
research
GET /v1/research/log
operation: get_research_log
Parameters
| name | in | required | type |
|---|---|---|---|
question | query | yes | string (uuid) |
Response 200
stringPOST /v1/research/log
The fast manual-entry path (`add_log_entry`'s doc comment in `stage2.rs`): a log entry with no accompanying evidence-creating op.
operation: add_log_entry
Request body
AddLogEntryRequest
| field | required | type |
|---|---|---|
search_context | yes | string |
session | yes | string (uuid) |
Response 200
(no body)
POST /v1/research/questions
Scope item 0 (additive change against WP-06's frozen I6, filed and recorded in the WP-07 spec): the research question/session/log-entry write routes did not exist yet — only `GET /v1/research/questions/{id}` and `GET /v1/research/log` did. This adds the 6 routes WP-07's MCP tool catalog needs, wrapping the already-frozen I5 ops in `crates/engine/src/ops/stage2.rs`.
operation: open_research_question
Request body
OpenResearchQuestionRequest
| field | required | type |
|---|---|---|
question | yes | string |
Response 200
(no body)
GET /v1/research/questions/{id}
operation: get_research_question
Parameters
| name | in | required | type |
|---|---|---|---|
id | path | yes | string (uuid) |
Response 200
ResearchQuestionDto
| field | required | type |
|---|---|---|
id | yes | string (uuid) |
question | yes | string |
Response 404
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
POST /v1/research/questions/{id}/close
operation: close_research_question
Parameters
| name | in | required | type |
|---|---|---|---|
id | path | yes | string (uuid) |
Response 200
(no body)
Response 404
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
POST /v1/research/questions/{id}/coverage-confirm
Human-only checkpoint (build-vs-spec reviewer pass, 2026-07-03; spec item 5's research route catalog + item 8's human-only-op list): the only checkpoint that can unlock a reasonably-exhaustive-search claim, wrapping the already-frozen `Engine::confirm_coverage` (I5, `crates/engine/src/ops/stage2.rs`). Same `require_human` pattern as `confirm_assertion`/`mark_fabricated`; `EngineError::NotFound` maps to 404 via the existing central error table (`problem.rs`).
operation: confirm_coverage
Parameters
| name | in | required | type |
|---|---|---|---|
id | path | yes | string (uuid) |
Response 200
(no body)
Response 403
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
Response 404
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
POST /v1/research/sessions
operation: start_session
Request body
StartSessionRequest
| field | required | type |
|---|---|---|
question | yes | string (uuid) |
Response 200
(no body)
Response 404
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
POST /v1/research/sessions/{id}/end
operation: end_session
Parameters
| name | in | required | type |
|---|---|---|---|
id | path | yes | string (uuid) |
Response 200
(no body)
sources
POST /v1/sources
`add_source` is "evidence-creating: no `ResearchContext` required" (an infrastructure record the research log doesn't need to narrate) — see `crates/engine/src/ops/stage2.rs`.
operation: post_source
Request body
CreateSourceRequest
| field | required | type |
|---|---|---|
title | yes | string |
Response 200
(no body)
GET /v1/sources/{id}
operation: get_source
Parameters
| name | in | required | type |
|---|---|---|---|
id | path | yes | string (uuid) |
Response 200
SourceDto
| field | required | type |
|---|---|---|
blobs | yes | array of string |
id | yes | string (uuid) |
title | yes | string |
Response 404
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |
Error model (problem+json)
Non-2xx responses use RFC 9457 application/problem+json.
Problem
| field | required | type |
|---|---|---|
detail | yes | string |
status | yes | integer (int32) |
title | yes | string |
type | yes | string |