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

nameinrequiredtype
personaqueryyesstring (uuid)

Response 200

array of

AssertionDto

fieldrequiredtype
claimyesstring
evidenceyesarray of

EvidenceView (tagged union)

kind = external_record

fieldrequiredtype
kindyesstring [enum: external_record]
recordyes

record (tagged union)

kind = ancestry_record

fieldrequiredtype
dbidyesstring
kindyesstring [enum: ancestry_record]
recordyesstring

kind = doi

fieldrequiredtype
doiyesstring
kindyesstring [enum: doi]

kind = family_search_ark

fieldrequiredtype
arkyesstring
kindyesstring [enum: family_search_ark]

kind = permalink

fieldrequiredtype
kindyesstring [enum: permalink]
urlyesstring

kind = source_blob

fieldrequiredtype
content_addressyesstring
kindyesstring [enum: source_blob]
fabricatedyesboolean
idyesstring (uuid)
personayesstring (uuid)
requested_byyesstring
sourceyesstring (uuid)
statusyesstring

POST /v1/assertions/capture

operation: capture_assertion

Request body

CaptureRequest

fieldrequiredtype
claimyesstring
personayesstring (uuid)
research_search_contextyesstring
research_sessionyesstring (uuid)
sourceyesstring (uuid)

Response 200

AssertionDto

fieldrequiredtype
claimyesstring
evidenceyesarray of

EvidenceView (tagged union)

kind = external_record

fieldrequiredtype
kindyesstring [enum: external_record]
recordyes

record (tagged union)

kind = ancestry_record

fieldrequiredtype
dbidyesstring
kindyesstring [enum: ancestry_record]
recordyesstring

kind = doi

fieldrequiredtype
doiyesstring
kindyesstring [enum: doi]

kind = family_search_ark

fieldrequiredtype
arkyesstring
kindyesstring [enum: family_search_ark]

kind = permalink

fieldrequiredtype
kindyesstring [enum: permalink]
urlyesstring

kind = source_blob

fieldrequiredtype
content_addressyesstring
kindyesstring [enum: source_blob]
fabricatedyesboolean
idyesstring (uuid)
personayesstring (uuid)
requested_byyesstring
sourceyesstring (uuid)
statusyesstring

Response 400

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

GET /v1/assertions/{id}

operation: get_assertion

Parameters

nameinrequiredtype
idpathyesstring (uuid)

Response 200

AssertionDto

fieldrequiredtype
claimyesstring
evidenceyesarray of

EvidenceView (tagged union)

kind = external_record

fieldrequiredtype
kindyesstring [enum: external_record]
recordyes

record (tagged union)

kind = ancestry_record

fieldrequiredtype
dbidyesstring
kindyesstring [enum: ancestry_record]
recordyesstring

kind = doi

fieldrequiredtype
doiyesstring
kindyesstring [enum: doi]

kind = family_search_ark

fieldrequiredtype
arkyesstring
kindyesstring [enum: family_search_ark]

kind = permalink

fieldrequiredtype
kindyesstring [enum: permalink]
urlyesstring

kind = source_blob

fieldrequiredtype
content_addressyesstring
kindyesstring [enum: source_blob]
fabricatedyesboolean
idyesstring (uuid)
personayesstring (uuid)
requested_byyesstring
sourceyesstring (uuid)
statusyesstring

Response 404

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

POST /v1/assertions/{id}/attach-evidence

operation: attach_evidence

Parameters

nameinrequiredtype
idpathyesstring (uuid)

Request body

AttachEvidenceRequest

fieldrequiredtype
evidenceyes

evidence

(object, no properties)

Response 200

(no body)

Response 400

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

Response 404

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

POST /v1/assertions/{id}/confirm

operation: confirm_assertion

Parameters

nameinrequiredtype
idpathyesstring (uuid)

Response 200

(no body)

Response 403

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

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

nameinrequiredtype
idpathyesstring (uuid)

Response 200

(no body)

Response 403

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

Response 422

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

audit

GET /v1/audit

operation: get_audit

Parameters

nameinrequiredtype
includequeryno['string', 'null']
limitqueryno['integer', 'null']

Response 200

array of

AuditEntryDto

fieldrequiredtype
actoryesstring
at_msyesinteger (int64)
event_typeyesstring
idyesstring (uuid)
payloadnoany

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

any

Response 200

BlobRefDto

fieldrequiredtype
blobyesstring

capabilities

GET /v1/capabilities

operation: get_capabilities

Response 200

CapabilitiesDto

fieldrequiredtype
api_versionyesstring
ingestyesarray of string

conflicts

GET /v1/conflicts

operation: list_conflicts

Response 200

array of

ConflictDto

fieldrequiredtype
assertionsyesarray of string (uuid)
idyesstring (uuid)
openyesboolean

diagnostics

GET /v1/diagnostics

operation: get_diagnostics

Response 200

DiagnosticsDto

fieldrequiredtype
log_location_descriptionyesstring

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

nameinrequiredtype
filenamequeryno['string', 'null']

Request body

any

Response 200

ImportSummaryDto

fieldrequiredtype
assertion_countyesinteger (int32)
dangling_pointer_countyesinteger
person_countyesinteger (int32)
persona_countyesinteger (int32)
raw_fileyesstring
source_countyesinteger (int32)
top_level_record_countsyesmap: string → integer (int32)
unmapped_tag_countsyesmap: string → integer (int32)

Response 422

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

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

fieldrequiredtype
actionyesstring
backup_path_descriptionyesstring
restart_requiredyesboolean

Response 403

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

Response 422

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

Response 500

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

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

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

GET /v1/jobs/{id}

operation: get_job

Parameters

nameinrequiredtype
idpathyesstring (uuid)

Response 501

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

pending

GET /v1/pending

operation: get_pending

Response 200

array of

AssertionDto

fieldrequiredtype
claimyesstring
evidenceyesarray of

EvidenceView (tagged union)

kind = external_record

fieldrequiredtype
kindyesstring [enum: external_record]
recordyes

record (tagged union)

kind = ancestry_record

fieldrequiredtype
dbidyesstring
kindyesstring [enum: ancestry_record]
recordyesstring

kind = doi

fieldrequiredtype
doiyesstring
kindyesstring [enum: doi]

kind = family_search_ark

fieldrequiredtype
arkyesstring
kindyesstring [enum: family_search_ark]

kind = permalink

fieldrequiredtype
kindyesstring [enum: permalink]
urlyesstring

kind = source_blob

fieldrequiredtype
content_addressyesstring
kindyesstring [enum: source_blob]
fabricatedyesboolean
idyesstring (uuid)
personayesstring (uuid)
requested_byyesstring
sourceyesstring (uuid)
statusyesstring

personas

POST /v1/personas

operation: post_persona

Request body

CreatePersonaRequest

fieldrequiredtype
labelyesstring
sourceyesstring (uuid)

Response 200

(no body)

GET /v1/personas/{id}

operation: get_persona

Parameters

nameinrequiredtype
idpathyesstring (uuid)

Response 200

PersonaDto

fieldrequiredtype
idyesstring (uuid)
labelyesstring
sourceyesstring (uuid)

Response 404

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

persons

GET /v1/persons

operation: list_persons

Response 200

array of

PersonDto

fieldrequiredtype
certaintyyesstring
idyesstring (uuid)

GET /v1/persons/{id}

operation: get_person

Parameters

nameinrequiredtype
idpathyesstring (uuid)

Response 200

PersonDto

fieldrequiredtype
certaintyyesstring
idyesstring (uuid)

Response 404

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

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

fieldrequiredtype
certaintyyes

certainty

(object, no properties)

claims_exhaustive_searchyesboolean
conclusionyesstring
contrary_evidenceyes

contrary_evidence

(object, no properties)

correlation_reasoningyesstring
questionyesstring (uuid)
supportingyesarray of string (uuid)

Response 200

ProofArgumentDto

fieldrequiredtype
certaintyyesstring
claims_exhaustive_searchyesboolean
conclusionyesstring
contrary_evidenceyesarray of

ContraryTreatmentView

fieldrequiredtype
assertionyesstring (uuid)
treatmentyesstring
correlation_reasoningyesstring
idyesstring (uuid)
questionyesstring (uuid)
supportingyesarray of string (uuid)

Response 400

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

Response 404

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

Response 422

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

proposals

GET /v1/proposals

operation: list_proposals

Response 200

array of

ProposalDto

fieldrequiredtype
destination_hintno['string', 'null']
idyesstring (uuid)
kindyesstring
reasonno['string', 'null']
requested_byyesstring
statusyesstring
targetno['string', 'null'] (uuid)

POST /v1/proposals

operation: propose

Request body

ProposeRedactRequest

fieldrequiredtype
reasonyesstring
targetyesstring (uuid)

Response 200

(no body)

POST /v1/proposals/{id}/approve

operation: approve_proposal

Parameters

nameinrequiredtype
idpathyesstring (uuid)

Request body

optional

ApproveRequest

fieldrequiredtype
summary_shownno['string', 'null']

Response 200

(no body)

Response 403

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

POST /v1/proposals/{id}/deny

operation: deny_proposal

Parameters

nameinrequiredtype
idpathyesstring (uuid)

Request body

DenyRequest

fieldrequiredtype
reasonyesstring

Response 200

(no body)

Response 403

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

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

fieldrequiredtype
reasonyesstring
summary_shownyesstring
targetyesstring (uuid)

Response 200

RedactionResultDto

fieldrequiredtype
blobs_purgedyesinteger
redactedyesboolean

Response 403

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

Response 409

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

research

GET /v1/research/log

operation: get_research_log

Parameters

nameinrequiredtype
questionqueryyesstring (uuid)

Response 200

array of string

POST /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

fieldrequiredtype
search_contextyesstring
sessionyesstring (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

fieldrequiredtype
questionyesstring

Response 200

(no body)

GET /v1/research/questions/{id}

operation: get_research_question

Parameters

nameinrequiredtype
idpathyesstring (uuid)

Response 200

ResearchQuestionDto

fieldrequiredtype
idyesstring (uuid)
questionyesstring

Response 404

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

POST /v1/research/questions/{id}/close

operation: close_research_question

Parameters

nameinrequiredtype
idpathyesstring (uuid)

Response 200

(no body)

Response 404

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

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

nameinrequiredtype
idpathyesstring (uuid)

Response 200

(no body)

Response 403

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

Response 404

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

POST /v1/research/sessions

operation: start_session

Request body

StartSessionRequest

fieldrequiredtype
questionyesstring (uuid)

Response 200

(no body)

Response 404

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

POST /v1/research/sessions/{id}/end

operation: end_session

Parameters

nameinrequiredtype
idpathyesstring (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

fieldrequiredtype
titleyesstring

Response 200

(no body)

GET /v1/sources/{id}

operation: get_source

Parameters

nameinrequiredtype
idpathyesstring (uuid)

Response 200

SourceDto

fieldrequiredtype
blobsyesarray of string
idyesstring (uuid)
titleyesstring

Response 404

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring

Error model (problem+json)

Non-2xx responses use RFC 9457 application/problem+json.

Problem

fieldrequiredtype
detailyesstring
statusyesinteger (int32)
titleyesstring
typeyesstring