API reference
Heartwood's local HTTP API: every action the app can take, as a documented route you can build your own tools against — loopback-only, on your own machine.
Giving an AI assistant a new capability instead of writing a standalone client? The same actions are also exposed as MCP tools — see the MCP reference.
Reference
GET /v1/assertions Preview
List assertions, paginated
The claims recorded against one persona, cursor-paginated. persona
is required — this route is scoped to a persona, not to a person,
so start from GET /v1/persons/{id} if all you have is a person id.
kind=, state= and source= narrow the set before it is paginated,
so total counts the matches. An unrecognised query parameter is a
400 rather than being ignored.
Parameters
personarequiredquerystring (uuid)Required. Assertions are listed per persona, so a caller holding a person id resolves it first —
GET /v1/persons/{id}returns that person's persona ids.kindquery optionalstringKeep only assertions whose
kindequals this string exactly (e.g."fact") — the same vocabulary a returned assertion'skinduses.statequery optionalstringKeep only assertions whose epistemic status equals this string exactly (e.g.
"confirmed"). The parameter is spelledstate; the field it filters is spelledstatusin the response body. Same vocabulary, different name.sourcequery optionalstring (uuid)Keep only assertions whose
sourceequals this source id.sortquery optionalstringHow to order the results.
"created"— by the assertion'screated_at_ms— is the only value accepted today; anything else is a 400. Absent ⇒ ordering by id.orderquery optionalstringasc(default, oldest first) ordesc(newest first). A cursor is only valid against the order it was minted under.limitquery optionalinteger (int32)How many rows to return. Clamped to
1..=500; defaults to 100 when absent. A value outside the range is clamped, not rejected.cursorquery optionalstringThe
next_cursorfrom the previous page. Omit it for the first page. Treat it as opaque, and keep every other query parameter identical while walking — a cursor is only valid against the query that minted it.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/assertions"POST /v1/assertions/capture Preview
Capture a new assertion with its evidence
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/assertions/capture"POST /v1/assertions/transcription-claim Preview
Claim a transcription of a source blob
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/assertions/transcription-claim"GET /v1/assertions/unsourced Preview
List assertions awaiting human evaluation, paginated
Parameters
limitquery optionalinteger (int32)How many rows to return. Clamped to
1..=500; defaults to 100 when absent. A value outside the range is clamped, not rejected.cursorquery optionalstringThe
next_cursorfrom the previous page. Omit it for the first page. Treat it as opaque, and keep every other query parameter identical while walking — a cursor is only valid against the query that minted it.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/assertions/unsourced"GET /v1/assertions/unsourced/tally Preview
Count how unsourced-surface claims split into sourced and needs-source
A client cannot get this by reading the listing's page total: that
figure counts both halves, so a surface labelling it "unsourced" says
the whole tree is unsourced, including the claims it renders as
sourced on the very same screen. total here is the sum of the two
halves, never an independent count.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/assertions/unsourced/tally"GET /v1/assertions/{id} Preview
Get an assertion by id
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/assertions/{id}"POST /v1/assertions/{id}/attach-evidence Preview
Attach evidence to an existing assertion
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/assertions/{id}/attach-evidence"POST /v1/assertions/{id}/confirm Preview
Confirm a pending assertion
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/assertions/{id}/confirm"POST /v1/assertions/{id}/mark-fabricated Preview
Mark an assertion as fabricated
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/assertions/{id}/mark-fabricated"POST /v1/assertions/{id}/refute Preview
Refute an assertion
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/assertions/{id}/refute"POST /v1/assertions/{id}/supersede Preview
Supersede an assertion with a replacement
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/assertions/{id}/supersede"GET /v1/trees/{tree_id}/assertions Preview
List assertions, paginated
The claims recorded against one persona, cursor-paginated. persona
is required — this route is scoped to a persona, not to a person,
so start from GET /v1/persons/{id} if all you have is a person id.
kind=, state= and source= narrow the set before it is paginated,
so total counts the matches. An unrecognised query parameter is a
400 rather than being ignored.
Parameters
personarequiredquerystring (uuid)Required. Assertions are listed per persona, so a caller holding a person id resolves it first —
GET /v1/persons/{id}returns that person's persona ids.kindquery optionalstringKeep only assertions whose
kindequals this string exactly (e.g."fact") — the same vocabulary a returned assertion'skinduses.statequery optionalstringKeep only assertions whose epistemic status equals this string exactly (e.g.
"confirmed"). The parameter is spelledstate; the field it filters is spelledstatusin the response body. Same vocabulary, different name.sourcequery optionalstring (uuid)Keep only assertions whose
sourceequals this source id.sortquery optionalstringHow to order the results.
"created"— by the assertion'screated_at_ms— is the only value accepted today; anything else is a 400. Absent ⇒ ordering by id.orderquery optionalstringasc(default, oldest first) ordesc(newest first). A cursor is only valid against the order it was minted under.limitquery optionalinteger (int32)How many rows to return. Clamped to
1..=500; defaults to 100 when absent. A value outside the range is clamped, not rejected.cursorquery optionalstringThe
next_cursorfrom the previous page. Omit it for the first page. Treat it as opaque, and keep every other query parameter identical while walking — a cursor is only valid against the query that minted it.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/assertions"POST /v1/trees/{tree_id}/assertions/capture Preview
Capture a new assertion with its evidence
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/assertions/capture"POST /v1/trees/{tree_id}/assertions/transcription-claim Preview
Claim a transcription of a source blob
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/assertions/transcription-claim"GET /v1/trees/{tree_id}/assertions/unsourced Preview
List assertions awaiting human evaluation, paginated
Parameters
limitquery optionalinteger (int32)How many rows to return. Clamped to
1..=500; defaults to 100 when absent. A value outside the range is clamped, not rejected.cursorquery optionalstringThe
next_cursorfrom the previous page. Omit it for the first page. Treat it as opaque, and keep every other query parameter identical while walking — a cursor is only valid against the query that minted it.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/assertions/unsourced"GET /v1/trees/{tree_id}/assertions/unsourced/tally Preview
Count how unsourced-surface claims split into sourced and needs-source
A client cannot get this by reading the listing's page total: that
figure counts both halves, so a surface labelling it "unsourced" says
the whole tree is unsourced, including the claims it renders as
sourced on the very same screen. total here is the sum of the two
halves, never an independent count.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/assertions/unsourced/tally"GET /v1/trees/{tree_id}/assertions/{id} Preview
Get an assertion by id
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/assertions/{id}"POST /v1/trees/{tree_id}/assertions/{id}/attach-evidence Preview
Attach evidence to an existing assertion
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/assertions/{id}/attach-evidence"POST /v1/trees/{tree_id}/assertions/{id}/confirm Preview
Confirm a pending assertion
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/assertions/{id}/confirm"POST /v1/trees/{tree_id}/assertions/{id}/mark-fabricated Preview
Mark an assertion as fabricated
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/assertions/{id}/mark-fabricated"POST /v1/trees/{tree_id}/assertions/{id}/refute Preview
Refute an assertion
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/assertions/{id}/refute"POST /v1/trees/{tree_id}/assertions/{id}/supersede Preview
Supersede an assertion with a replacement
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/assertions/{id}/supersede"POST /v1/associations Preview
Create an association between persons
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/associations"POST /v1/trees/{tree_id}/associations Preview
Create an association between persons
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/associations"GET /v1/audit Preview
Get the audit trail
Parameters
includequery optionalstringlimitquery optionalinteger (int32)cursorquery optionalstring
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/audit"GET /v1/trees/{tree_id}/audit Preview
Get the audit trail
Parameters
includequery optionalstringlimitquery optionalinteger (int32)cursorquery optionalstring
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/audit"GET /v1/backup/config Preview
Get the backup configuration
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/backup/config"PUT /v1/backup/config Preview
Set the backup configuration
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
PutBackupConfigRequest
backup_root_pathoptionalstringcadence_hoursrequiredinteger (int32)enabledrequiredbooleanretentionrequiredBackupRetentionDto
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/backup/config"GET /v1/backup/manifests Preview
List the backups under a backup root
Lists the backups found under a backup root — including a root this
machine has never had configured, which is the case that matters when
restoring onto a replacement computer. Requires the human token.
The service walks the root and parses each manifest itself, refusing
any whose format version it does not understand rather than guessing.
A root that was read and holds no recognizable backups returns an
empty list. A root that could not be read — absent, not a folder,
or not a full path — is 422, never an empty list: an unmounted drive
is this flow's likeliest failure, and "no backups found" is the one
answer that would make a user stop looking for data that is still
there. Nothing in the response carries a filesystem path back out.
Parameters
backup_rootrequiredquerystring
Responses
200
BackupManifestsDto
manifestsrequiredarray ofBackupManifestDto
app_versionoptionalstringbackup_idrequiredstringcreated_at_msoptionalinteger (int64)event_countoptionalinteger (int64)object_countoptionalinteger (int64)total_bytesoptionalinteger (int64)tree_idrequiredstringtree_nameoptionalstringunreadableoptionalstring
403
422
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/backup/manifests"GET /v1/backup/status Preview
Get the backup status
Responses
200
BackupStatusDto
backup_location_descriptionrequiredstringconfiguredrequiredbooleanenabledrequiredbooleanlast_failure_at_msoptionalinteger (int64)last_failure_classoptionalstringlast_success_at_msoptionalinteger (int64)next_run_at_msoptionalinteger (int64)
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/backup/status"POST /v1/restore Preview
Restore a backup into a new tree
Restores one backup into a new tree. Requires the human token.
The restore never overwrites an existing tree, and it does not change
which tree is active — switching to the restored tree is a separate,
explicit call to PUT /v1/trees/active. Every object is re-hashed
against the backup manifest before a byte is written; the response
reports how many objects and bytes were verified.
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
RestoreRequest
backup_idrequiredstringbackup_rootrequiredstringtree_idrequiredstring
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/restore"POST /v1/blobs Preview
Upload a blob
Stores raw bytes and returns their content address. Send the bytes as
the request body with Content-Type: application/octet-stream; the
address that comes back is what every other route means by a blob
reference (bare hex, 64 characters).
The body is streamed rather than buffered, so upload size is bounded
by the ceiling below rather than by memory. A body that exceeds the
ceiling is refused with 413 while it is still arriving, and the
partial upload is discarded — a rejected upload leaves nothing
behind.
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/blobs"GET /v1/blobs/{address} Preview
Download a blob by content address
Parameters
addressrequiredpathstringsha256:<hex> content address
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/blobs/{address}"POST /v1/trees/{tree_id}/blobs Preview
Upload a blob
Stores raw bytes and returns their content address. Send the bytes as
the request body with Content-Type: application/octet-stream; the
address that comes back is what every other route means by a blob
reference (bare hex, 64 characters).
The body is streamed rather than buffered, so upload size is bounded
by the ceiling below rather than by memory. A body that exceeds the
ceiling is refused with 413 while it is still arriving, and the
partial upload is discarded — a rejected upload leaves nothing
behind.
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/blobs"GET /v1/trees/{tree_id}/blobs/{address} Preview
Download a blob by content address
Parameters
addressrequiredpathstringsha256:<hex> content address
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/blobs/{address}"GET /v1/capabilities Preview
Get the daemon's advertised capabilities
Responses
200
CapabilitiesDto
api_versionrequiredstringapp_versionrequiredstringingestrequired array ofstringplatformrequiredstring
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/capabilities"GET /v1/citation-templates Preview
List available citation templates
Parameters
categoryquery optionalstring
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/citation-templates"POST /v1/citations Preview
Create a general-purpose citation from typed elements
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/citations"POST /v1/citations/render Preview
Render a citation to formatted text
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/citations/render"PUT /v1/citations/{id}/elements Preview
Set a citation's structured elements
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/citations/{id}/elements"PUT /v1/citations/{id}/source-type Preview
Record what kind of record a source is
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/citations/{id}/source-type"GET /v1/trees/{tree_id}/citation-templates Preview
List available citation templates
Parameters
categoryquery optionalstring
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/citation-templates"POST /v1/trees/{tree_id}/citations Preview
Create a general-purpose citation from typed elements
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/citations"POST /v1/trees/{tree_id}/citations/render Preview
Render a citation to formatted text
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/citations/render"PUT /v1/trees/{tree_id}/citations/{id}/elements Preview
Set a citation's structured elements
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/citations/{id}/elements"PUT /v1/trees/{tree_id}/citations/{id}/source-type Preview
Record what kind of record a source is
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/citations/{id}/source-type"GET /v1/conflicts Preview
List detected conflicts
Each row names the persona or person it belongs to and carries the
claims that disagree, each already joined to the source that made it
— so a caller can describe the dispute without fetching anything
else. Filter with persona or person to get only one subject's
conflicts; pass neither for the whole tree.
Parameters
personaquery optionalstring (uuid)Only conflicts recorded against this persona.
personquery optionalstring (uuid)Only conflicts about this person's identity, plus every conflict on a persona this person concludes over.
limitquery optionalinteger (int32)cursorquery optionalstring
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/conflicts"POST /v1/conflicts/{id}/resolution Preview
Resolve a conflict with a proof argument
Returns the updated conflict, now closed. A conflict is settled once
and only once: resolving one that is already settled is a 409, and
naming a conflict or an argument that does not exist is a 404.
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/conflicts/{id}/resolution"GET /v1/trees/{tree_id}/conflicts Preview
List detected conflicts
Each row names the persona or person it belongs to and carries the
claims that disagree, each already joined to the source that made it
— so a caller can describe the dispute without fetching anything
else. Filter with persona or person to get only one subject's
conflicts; pass neither for the whole tree.
Parameters
personaquery optionalstring (uuid)Only conflicts recorded against this persona.
personquery optionalstring (uuid)Only conflicts about this person's identity, plus every conflict on a persona this person concludes over.
limitquery optionalinteger (int32)cursorquery optionalstring
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/conflicts"POST /v1/trees/{tree_id}/conflicts/{id}/resolution Preview
Resolve a conflict with a proof argument
Returns the updated conflict, now closed. A conflict is settled once
and only once: resolving one that is already settled is a 409, and
naming a conflict or an argument that does not exist is a 404.
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/conflicts/{id}/resolution"GET /v1/diagnostics Preview
Get diagnostics summary
Responses
200
DiagnosticsDto
log_location_descriptionoptionalstring
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/diagnostics"GET /v1/diagnostics/bundle Preview
Download a diagnostics bundle
Responses
200 — text/plain redacted diagnostics bundle
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/diagnostics/bundle"POST /v1/feedback Preview
Send feedback to the Heartwood team
Sends user-typed feedback to the Heartwood team. Requires the human
token: this is the one route that sends text off the machine, so an
agent credential can never call it.
The request body carries only what the user typed. The app version and
platform are filled in by the service itself and echoed back in the
response, so a client cannot misreport which build a message came from
— and can show the user the exact values before sending.
The outcome is never flattened into a generic success. 202 means
delivered; 429 rate limited; 503 the service is not accepting
submissions; 502 it could not be reached; 422 the message was
refused before it left the machine. No response reports success for a
message that was not delivered.
Tier: preview — a first-party surface for this app's own window, not
something a third party should build against, but it may still change
shape between minor versions.
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
SubmitFeedbackRequest
emailoptionalstringmessagerequiredstringnameoptionalstring
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/feedback"POST /v1/events Preview
Create a life event
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/events"GET /v1/events/stream Preview
Subscribe to the live change-event stream (SSE)
A text/event-stream of change notices, so a client can refetch what
moved instead of polling. The feed is best-effort and has no replay: a
client that connects late has missed the earlier events and catches up
by re-reading state, not by rewinding the stream.
The two mounts of this route behave differently, deliberately:
* /v1/trees/{tree_id}/events/stream stays pinned to that one tree
for the life of the connection.
* /v1/events/stream follows whichever tree is currently active. When
the active tree changes it re-subscribes to the new tree and emits a
tree.active_changed event, which is a client's cue to refetch
once.
Responses
200 — text/event-stream of change notices
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/events/stream"GET /v1/events/{id} Preview
Get a life event by id
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/events/{id}"POST /v1/events/{id}/corrections Preview
Correct a life event's details
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/events/{id}/corrections"POST /v1/events/{id}/participants Preview
Add a participant to a life event
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/events/{id}/participants"POST /v1/trees/{tree_id}/events Preview
Create a life event
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/events"GET /v1/trees/{tree_id}/events/stream Preview
Subscribe to the live change-event stream (SSE)
A text/event-stream of change notices, so a client can refetch what
moved instead of polling. The feed is best-effort and has no replay: a
client that connects late has missed the earlier events and catches up
by re-reading state, not by rewinding the stream.
The two mounts of this route behave differently, deliberately:
* /v1/trees/{tree_id}/events/stream stays pinned to that one tree
for the life of the connection.
* /v1/events/stream follows whichever tree is currently active. When
the active tree changes it re-subscribes to the new tree and emits a
tree.active_changed event, which is a client's cue to refetch
once.
Responses
200 — text/event-stream of change notices
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/events/stream"GET /v1/trees/{tree_id}/events/{id} Preview
Get a life event by id
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/events/{id}"POST /v1/trees/{tree_id}/events/{id}/corrections Preview
Correct a life event's details
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/events/{id}/corrections"POST /v1/trees/{tree_id}/events/{id}/participants Preview
Add a participant to a life event
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/events/{id}/participants"POST /v1/gedcom/export Preview
Export the tree to GEDCOM (family file) format
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/gedcom/export"GET /v1/gedcom/loss-reports Preview
Get a GEDCOM import's loss report
Parameters
report_idquery optionalstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/gedcom/loss-reports"POST /v1/gedcom/validate Preview
Validate a GEDCOM (family file) without importing
Parameters
version_hintquery optionalstringidempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/gedcom/validate"GET /v1/imports Preview
List import runs
Responses
200
ImportRecordDtoExample
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/imports"POST /v1/imports/gedcom Preview
Import a GEDCOM (family file) into the tree
Parameters
filenamequery optionalstringallow_duplicatequerybooleanDefault
false. Uploading bytes identical to a previous import refuses synchronously with409 duplicate-import, before any job is spawned. Set this to import the same file a second time on purpose.idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/imports/gedcom"POST /v1/imports/{import_key}/undo Preview
Undo a GEDCOM import
Parameters
import_keyrequiredpathstringidempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/imports/{import_key}/undo"POST /v1/trees/{tree_id}/gedcom/export Preview
Export the tree to GEDCOM (family file) format
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/gedcom/export"GET /v1/trees/{tree_id}/gedcom/loss-reports Preview
Get a GEDCOM import's loss report
Parameters
report_idquery optionalstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/gedcom/loss-reports"POST /v1/trees/{tree_id}/gedcom/validate Preview
Validate a GEDCOM (family file) without importing
Parameters
version_hintquery optionalstringidempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/gedcom/validate"GET /v1/trees/{tree_id}/imports Preview
List import runs
Responses
200
ImportRecordDtoExample
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/imports"POST /v1/trees/{tree_id}/imports/gedcom Preview
Import a GEDCOM (family file) into the tree
Parameters
filenamequery optionalstringallow_duplicatequerybooleanDefault
false. Uploading bytes identical to a previous import refuses synchronously with409 duplicate-import, before any job is spawned. Set this to import the same file a second time on purpose.idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/imports/gedcom"POST /v1/trees/{tree_id}/imports/{import_key}/undo Preview
Undo a GEDCOM import
Parameters
import_keyrequiredpathstringidempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/imports/{import_key}/undo"POST /v1/integrations/claude-desktop/connect Preview
Connect Claude Desktop to this instance
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/integrations/claude-desktop/connect"POST /v1/integrations/claude-desktop/connect/preview Preview
Preview connecting Claude Desktop, without writing anything
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/integrations/claude-desktop/connect/preview"GET /v1/integrations/harnesses Preview
List known harnesses and which support one-click connect
Responses
200
HarnessListResponseDto
harnessesrequiredarray ofHarnessListItemDto
display_namerequiredstringidrequiredstringone_clickrequiredbooleanvendorrequiredstring
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/integrations/harnesses"GET /v1/jobs Preview
List background jobs
Parameters
limitquery optionalinteger (int32)How many rows to return. Clamped to
1..=500; defaults to 100 when absent. A value outside the range is clamped, not rejected.cursorquery optionalstringThe
next_cursorfrom the previous page. Omit it for the first page. Treat it as opaque, and keep every other query parameter identical while walking — a cursor is only valid against the query that minted it.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/jobs"GET /v1/jobs/{id} Preview
Get a background job's status
Parameters
idrequiredpathstring (uuid)
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/jobs/{id}"POST /v1/jobs/{id}/cancel Preview
Cancel a background job
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/jobs/{id}/cancel"GET /v1/trees/{tree_id}/jobs Preview
List background jobs
Parameters
limitquery optionalinteger (int32)How many rows to return. Clamped to
1..=500; defaults to 100 when absent. A value outside the range is clamped, not rejected.cursorquery optionalstringThe
next_cursorfrom the previous page. Omit it for the first page. Treat it as opaque, and keep every other query parameter identical while walking — a cursor is only valid against the query that minted it.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/jobs"GET /v1/trees/{tree_id}/jobs/{id} Preview
Get a background job's status
Parameters
idrequiredpathstring (uuid)
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/jobs/{id}"POST /v1/trees/{tree_id}/jobs/{id}/cancel Preview
Cancel a background job
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/jobs/{id}/cancel"GET /v1/labels Preview
Resolve entity ids to display labels
Turns a batch of entity ids into the names a human reads. Reads that
return ids only — GET /v1/audit above all — pair with this route so
a caller can render a readable timeline in one extra call instead of
one call per row.
Ids are globally unique across every entity kind, so no kind hint is
needed or accepted. An id that resolves to nothing is omitted from
the response rather than reported as an error: a partly-resolving
batch is the normal case (an entity may have been redacted or
removed), and the response tells you what it found, in any order.
Every label returned here is one the same caller could already read
from GET /v1/persons/{id} and its siblings; this route is a
convenience, not a new grant.
Parameters
idsrequiredquerystringComma-separated entity ids.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/labels"GET /v1/trees/{tree_id}/labels Preview
Resolve entity ids to display labels
Turns a batch of entity ids into the names a human reads. Reads that
return ids only — GET /v1/audit above all — pair with this route so
a caller can render a readable timeline in one extra call instead of
one call per row.
Ids are globally unique across every entity kind, so no kind hint is
needed or accepted. An id that resolves to nothing is omitted from
the response rather than reported as an error: a partly-resolving
batch is the normal case (an entity may have been redacted or
removed), and the response tells you what it found, in any order.
Every label returned here is one the same caller could already read
from GET /v1/persons/{id} and its siblings; this route is a
convenience, not a new grant.
Parameters
idsrequiredquerystringComma-separated entity ids.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/labels"GET /v1/media/unresolved Preview
List media this machine has not read in, by file name
No folder is reported and none is accepted: a caller supplies bytes by
uploading them to POST /v1/blobs and naming the returned address to
POST /v1/media/{id}/resolve. Returns every row in one response.
Responses
200
UnresolvedMediaDtoExample
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/media/unresolved"POST /v1/media/{id}/resolve Preview
Resolve a media object from an already-uploaded blob
The blob becomes this tree's own copy, so whatever the caller read it
from may afterwards be moved, renamed or deleted with no effect here.
Answers 200 with status: "already_resolved" when the file already
read from these exact bytes — a no-op rather than a refusal. Naming a
different blob for a file that already has one is a correction, not
a no-op: it lands, and status is resolved. That is what makes
attaching the wrong file recoverable, since media.resolved.v1 has no
undo route.
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/media/{id}/resolve"GET /v1/trees/{tree_id}/media/unresolved Preview
List media this machine has not read in, by file name
No folder is reported and none is accepted: a caller supplies bytes by
uploading them to POST /v1/blobs and naming the returned address to
POST /v1/media/{id}/resolve. Returns every row in one response.
Responses
200
UnresolvedMediaDtoExample
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/media/unresolved"POST /v1/trees/{tree_id}/media/{id}/resolve Preview
Resolve a media object from an already-uploaded blob
The blob becomes this tree's own copy, so whatever the caller read it
from may afterwards be moved, renamed or deleted with no effect here.
Answers 200 with status: "already_resolved" when the file already
read from these exact bytes — a no-op rather than a refusal. Naming a
different blob for a file that already has one is a correction, not
a no-op: it lands, and status is resolved. That is what makes
attaching the wrong file recoverable, since media.resolved.v1 has no
undo route.
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/media/{id}/resolve"GET /v1/notes Preview
List notes
Parameters
targetrequiredquerystring
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/notes"POST /v1/notes Preview
Create a note
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
201
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/notes"GET /v1/trees/{tree_id}/notes Preview
List notes
Parameters
targetrequiredquerystring
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/notes"POST /v1/trees/{tree_id}/notes Preview
Create a note
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
201
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/notes"GET /v1/pending Preview
List assertions in the pending lane
The review queue: assertions an agent has proposed that no human has
accepted or rejected yet. Cursor-paginated like every other collection
route.
source= and proposer= narrow the set; sort=created with order=
controls ordering; group_by=source|proposer switches the response
from a flat page to buckets — see the response schema for how the two
shapes differ.
Confirming or rejecting an item removes it from this queue: use
POST /v1/assertions/{id}/confirm, .../refute, or
POST /v1/pending/bulk-confirm for a whole batch.
Parameters
sourcequery optionalstring (uuid)Keep only pending items whose
sourceequals this source id.proposerquery optionalstringKeep only pending items whose
proposerequals this string — the model identifier the creating agent reported for itself.sortquery optionalstringHow to order the results.
"created"is the only value accepted today.orderquery optionalstringasc(default, oldest first) ordesc(newest first). A cursor is only valid against the order it was minted under.limitquery optionalinteger (int32)How many rows to return. Clamped to
1..=500; defaults to 100 when absent. A value outside the range is clamped, not rejected.cursorquery optionalstringThe
next_cursorfrom the previous page. Omit it for the first page. Treat it as opaque, and keep every other query parameter identical while walking — a cursor is only valid against the query that minted it.group_byquery optionalstringReturn the (already filtered and sorted) result set bucketed by
sourceor byproposerinstead of as a flat page. See this route's own description for how that changes the response shape.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/pending"POST /v1/pending/bulk-confirm Preview
Bulk-confirm pending assertions
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/pending/bulk-confirm"POST /v1/pending/{id}/defer Preview
Defer a pending assertion
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/pending/{id}/defer"POST /v1/pending/{id}/undefer Preview
Undefer a previously-deferred pending assertion
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/pending/{id}/undefer"GET /v1/trees/{tree_id}/pending Preview
List assertions in the pending lane
The review queue: assertions an agent has proposed that no human has
accepted or rejected yet. Cursor-paginated like every other collection
route.
source= and proposer= narrow the set; sort=created with order=
controls ordering; group_by=source|proposer switches the response
from a flat page to buckets — see the response schema for how the two
shapes differ.
Confirming or rejecting an item removes it from this queue: use
POST /v1/assertions/{id}/confirm, .../refute, or
POST /v1/pending/bulk-confirm for a whole batch.
Parameters
sourcequery optionalstring (uuid)Keep only pending items whose
sourceequals this source id.proposerquery optionalstringKeep only pending items whose
proposerequals this string — the model identifier the creating agent reported for itself.sortquery optionalstringHow to order the results.
"created"is the only value accepted today.orderquery optionalstringasc(default, oldest first) ordesc(newest first). A cursor is only valid against the order it was minted under.limitquery optionalinteger (int32)How many rows to return. Clamped to
1..=500; defaults to 100 when absent. A value outside the range is clamped, not rejected.cursorquery optionalstringThe
next_cursorfrom the previous page. Omit it for the first page. Treat it as opaque, and keep every other query parameter identical while walking — a cursor is only valid against the query that minted it.group_byquery optionalstringReturn the (already filtered and sorted) result set bucketed by
sourceor byproposerinstead of as a flat page. See this route's own description for how that changes the response shape.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/pending"POST /v1/trees/{tree_id}/pending/bulk-confirm Preview
Bulk-confirm pending assertions
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/pending/bulk-confirm"POST /v1/trees/{tree_id}/pending/{id}/defer Preview
Defer a pending assertion
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/pending/{id}/defer"POST /v1/trees/{tree_id}/pending/{id}/undefer Preview
Undefer a previously-deferred pending assertion
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/pending/{id}/undefer"POST /v1/personas Preview
Create a persona
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
200
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/personas"GET /v1/personas/{id} Preview
Get a persona by id
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/personas/{id}"PUT /v1/personas/{id}/name-pieces Preview
Set a persona's structured name pieces
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/personas/{id}/name-pieces"POST /v1/trees/{tree_id}/personas Preview
Create a persona
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
200
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/personas"GET /v1/trees/{tree_id}/personas/{id} Preview
Get a persona by id
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/personas/{id}"PUT /v1/trees/{tree_id}/personas/{id}/name-pieces Preview
Set a persona's structured name pieces
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/personas/{id}/name-pieces"GET /v1/fan/query Preview
Query the fan-network relationship view by parameters
Parameters
persona_idquery optionalstring (uuid)person_idquery optionalstring (uuid)window_startquery optionalstringwindow_endquery optionalstringedge_typesquery optionalstringComma-separated
shared_event/association/place_co_occurrence(default: all three).cursorquery optionalstringlimitquery optionalinteger (int32)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/fan/query"GET /v1/persons Preview
List persons, paginated
Every person in the tree, cursor-paginated. q= searches names,
sort=/order= control ordering, and limit=/cursor= page through
the result — see each parameter for the details.
A query parameter this route does not recognise is a 400, never
silently ignored, so a typo in a filter name fails loudly instead of
returning an unfiltered page that looks right.
Parameters
qquery optionalstringFree-text person-name search. Matches a name prefix first and falls back to a substring match when no prefix hits. Results come back in relevance order, so a
sort/ordergiven alongsideqis accepted but ignored rather than rejected. Absent ⇒ no name filter.sortquery optionalstringHow to order the results: *
name— the person's display name. *surname— the display name's last whitespace-separated token, then the full name. *birth— earliest recorded birth year; people with no recorded birth sort last. *updated— when the person record was last touched. Any other value is a 400. Absent ⇒ a stable but arbitrary order by id. Sorting is applied before paging, so page 2 continues page 1.orderquery optionalstringasc(default, oldest first) ordesc(newest first). A cursor is only valid against the order it was minted under.limitquery optionalinteger (int32)How many rows to return. Clamped to
1..=500; defaults to 100 when absent. A value outside the range is clamped, not rejected.cursorquery optionalstringThe
next_cursorfrom the previous page. Omit it for the first page. Treat it as opaque, and keep every other query parameter identical while walking — a cursor is only valid against the query that minted it.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/persons"POST /v1/persons Preview
Conclude a new person over a set of personas
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/persons"GET /v1/persons/duplicate-candidates Preview
Rank likely-existing duplicates of a person being entered
Parameters
givenquery optionalstringGiven name as typed so far (whitespace-separated pieces).
surnamequery optionalstringSurname as typed so far.
birthquery optionalstringBirth date in GEDCOM syntax (
1832,ABT 1832,12 JAN 1900,BEF 1900) — the same grammar every entry-form date field takes. Unparseable text 400s; scoring without a typed date would misrank and hide why.deathquery optionalstringDeath date, same syntax and same strictness as
birth.limitquery optionalinteger (int32)Max candidates returned (default 8, cap 50) — an entry form wants a short "did you mean?" list, not a page walk.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/persons/duplicate-candidates"POST /v1/persons/merge Preview
Merge two persons into one
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/persons/merge"GET /v1/persons/{id} Preview
Get a person's detail record by id
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/persons/{id}"GET /v1/persons/{id}/card Preview
Get a person's orientation card (name, lifespan, immediate family, source coverage)
Parameters
idrequiredpathstring (uuid)expandquery optionalstringComma-separated related record sets to inline: any of
events,assertions,sources. Omit for the counts-only card. Each expanded list is capped at 100 rows. An unrecognised name is a 400, never a silently unexpanded card.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/persons/{id}/card"GET /v1/persons/{id}/fan-network Preview
Get the fan-network relationship view centered on a person
Parameters
idrequiredpathstring (uuid)window_startquery optionalstringwindow_endquery optionalstringedge_typesquery optionalstringComma-separated
shared_event/association/place_co_occurrence(default: all three).
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/persons/{id}/fan-network"PUT /v1/persons/{id}/living-status Preview
Set a person's living-status override
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/persons/{id}/living-status"GET /v1/persons/{id}/pedigree Preview
Get a person's ancestor pedigree as Ahnentafel-numbered slots
Parameters
idrequiredpathstring (uuid)generationsquery optionalinteger (int32)How many ancestor generations to resolve, from 1 to 10 (default 4). Anything outside that range is a 400.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/persons/{id}/pedigree"POST /v1/persons/{id}/retract Preview
Retract a mistaken person conclusion
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/persons/{id}/retract"POST /v1/persons/{id}/split Preview
Split a person into two, reversing a conclusion or merge
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/persons/{id}/split"GET /v1/trees/{tree_id}/fan/query Preview
Query the fan-network relationship view by parameters
Parameters
persona_idquery optionalstring (uuid)person_idquery optionalstring (uuid)window_startquery optionalstringwindow_endquery optionalstringedge_typesquery optionalstringComma-separated
shared_event/association/place_co_occurrence(default: all three).cursorquery optionalstringlimitquery optionalinteger (int32)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/fan/query"GET /v1/trees/{tree_id}/persons Preview
List persons, paginated
Every person in the tree, cursor-paginated. q= searches names,
sort=/order= control ordering, and limit=/cursor= page through
the result — see each parameter for the details.
A query parameter this route does not recognise is a 400, never
silently ignored, so a typo in a filter name fails loudly instead of
returning an unfiltered page that looks right.
Parameters
qquery optionalstringFree-text person-name search. Matches a name prefix first and falls back to a substring match when no prefix hits. Results come back in relevance order, so a
sort/ordergiven alongsideqis accepted but ignored rather than rejected. Absent ⇒ no name filter.sortquery optionalstringHow to order the results: *
name— the person's display name. *surname— the display name's last whitespace-separated token, then the full name. *birth— earliest recorded birth year; people with no recorded birth sort last. *updated— when the person record was last touched. Any other value is a 400. Absent ⇒ a stable but arbitrary order by id. Sorting is applied before paging, so page 2 continues page 1.orderquery optionalstringasc(default, oldest first) ordesc(newest first). A cursor is only valid against the order it was minted under.limitquery optionalinteger (int32)How many rows to return. Clamped to
1..=500; defaults to 100 when absent. A value outside the range is clamped, not rejected.cursorquery optionalstringThe
next_cursorfrom the previous page. Omit it for the first page. Treat it as opaque, and keep every other query parameter identical while walking — a cursor is only valid against the query that minted it.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/persons"POST /v1/trees/{tree_id}/persons Preview
Conclude a new person over a set of personas
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/persons"GET /v1/trees/{tree_id}/persons/duplicate-candidates Preview
Rank likely-existing duplicates of a person being entered
Parameters
givenquery optionalstringGiven name as typed so far (whitespace-separated pieces).
surnamequery optionalstringSurname as typed so far.
birthquery optionalstringBirth date in GEDCOM syntax (
1832,ABT 1832,12 JAN 1900,BEF 1900) — the same grammar every entry-form date field takes. Unparseable text 400s; scoring without a typed date would misrank and hide why.deathquery optionalstringDeath date, same syntax and same strictness as
birth.limitquery optionalinteger (int32)Max candidates returned (default 8, cap 50) — an entry form wants a short "did you mean?" list, not a page walk.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/persons/duplicate-candidates"POST /v1/trees/{tree_id}/persons/merge Preview
Merge two persons into one
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/persons/merge"GET /v1/trees/{tree_id}/persons/{id} Preview
Get a person's detail record by id
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/persons/{id}"GET /v1/trees/{tree_id}/persons/{id}/card Preview
Get a person's orientation card (name, lifespan, immediate family, source coverage)
Parameters
idrequiredpathstring (uuid)expandquery optionalstringComma-separated related record sets to inline: any of
events,assertions,sources. Omit for the counts-only card. Each expanded list is capped at 100 rows. An unrecognised name is a 400, never a silently unexpanded card.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/persons/{id}/card"GET /v1/trees/{tree_id}/persons/{id}/fan-network Preview
Get the fan-network relationship view centered on a person
Parameters
idrequiredpathstring (uuid)window_startquery optionalstringwindow_endquery optionalstringedge_typesquery optionalstringComma-separated
shared_event/association/place_co_occurrence(default: all three).
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/persons/{id}/fan-network"PUT /v1/trees/{tree_id}/persons/{id}/living-status Preview
Set a person's living-status override
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/persons/{id}/living-status"GET /v1/trees/{tree_id}/persons/{id}/pedigree Preview
Get a person's ancestor pedigree as Ahnentafel-numbered slots
Parameters
idrequiredpathstring (uuid)generationsquery optionalinteger (int32)How many ancestor generations to resolve, from 1 to 10 (default 4). Anything outside that range is a 400.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/persons/{id}/pedigree"POST /v1/trees/{tree_id}/persons/{id}/retract Preview
Retract a mistaken person conclusion
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/persons/{id}/retract"POST /v1/trees/{tree_id}/persons/{id}/split Preview
Split a person into two, reversing a conclusion or merge
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/persons/{id}/split"GET /v1/proof-arguments Preview
List proof arguments, paginated
Parameters
questionquery optionalstring (uuid)cursorquery optionalstringlimitquery optionalinteger (int32)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/proof-arguments"POST /v1/proof-arguments Preview
Create a proof argument
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/proof-arguments"GET /v1/proof-arguments/{id} Preview
Get a proof argument by id
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/proof-arguments/{id}"GET /v1/proof-arguments/{id}/export Preview
Export a proof argument
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/proof-arguments/{id}/export"GET /v1/trees/{tree_id}/proof-arguments Preview
List proof arguments, paginated
Parameters
questionquery optionalstring (uuid)cursorquery optionalstringlimitquery optionalinteger (int32)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/proof-arguments"POST /v1/trees/{tree_id}/proof-arguments Preview
Create a proof argument
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/proof-arguments"GET /v1/trees/{tree_id}/proof-arguments/{id} Preview
Get a proof argument by id
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/proof-arguments/{id}"GET /v1/trees/{tree_id}/proof-arguments/{id}/export Preview
Export a proof argument
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/proof-arguments/{id}/export"GET /v1/proposals Preview
List pending merge proposals
Parameters
limitquery optionalinteger (int32)How many rows to return. Clamped to
1..=500; defaults to 100 when absent. A value outside the range is clamped, not rejected.cursorquery optionalstringThe
next_cursorfrom the previous page. Omit it for the first page. Treat it as opaque, and keep every other query parameter identical while walking — a cursor is only valid against the query that minted it.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/proposals"POST /v1/proposals Preview
Propose a merge
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
200
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/proposals"POST /v1/proposals/{id}/approve Preview
Approve a merge proposal
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (optional)
ApproveRequestResponses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/proposals/{id}/approve"POST /v1/proposals/{id}/deny Preview
Deny a merge proposal
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/proposals/{id}/deny"GET /v1/trees/{tree_id}/proposals Preview
List pending merge proposals
Parameters
limitquery optionalinteger (int32)How many rows to return. Clamped to
1..=500; defaults to 100 when absent. A value outside the range is clamped, not rejected.cursorquery optionalstringThe
next_cursorfrom the previous page. Omit it for the first page. Treat it as opaque, and keep every other query parameter identical while walking — a cursor is only valid against the query that minted it.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/proposals"POST /v1/trees/{tree_id}/proposals Preview
Propose a merge
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
200
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/proposals"POST /v1/trees/{tree_id}/proposals/{id}/approve Preview
Approve a merge proposal
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (optional)
ApproveRequestResponses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/proposals/{id}/approve"POST /v1/trees/{tree_id}/proposals/{id}/deny Preview
Deny a merge proposal
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/proposals/{id}/deny"POST /v1/redactions Preview
Redact a record
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/redactions"POST /v1/trees/{tree_id}/redactions Preview
Redact a record
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/redactions"POST /v1/relationships Preview
Attach a parent or spouse edge between two persons
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/relationships"POST /v1/relationships/reparent Preview
Replace a child's parent with a different parent
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/relationships/reparent"POST /v1/relationships/unlink Preview
Remove a parent or spouse edge between two persons
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/relationships/unlink"POST /v1/trees/{tree_id}/relationships Preview
Attach a parent or spouse edge between two persons
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/relationships"POST /v1/trees/{tree_id}/relationships/reparent Preview
Replace a child's parent with a different parent
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/relationships/reparent"POST /v1/trees/{tree_id}/relationships/unlink Preview
Remove a parent or spouse edge between two persons
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/relationships/unlink"GET /v1/project/state Preview
The session brief — current investigation state as a bounded digest
Parameters
sincequery optionalstringThe
cursorvalue from a previous brief; restricts every section to what changed after it. Omit for the full digest.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/project/state"GET /v1/research/log Preview
Get the research log for a session
Parameters
questionrequiredquerystring (uuid)
Responses
200
stringExample
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/log"POST /v1/research/log Preview
Add a search/source entry to the research log
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
200
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/log"POST /v1/research/log/capture Preview
Capture a research-log entry with evidence
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/log/capture"GET /v1/research/log/entries Preview
List research-log entries
Parameters
questionquery optionalstring (uuid)sessionquery optionalstring (uuid)personaquery optionalstring (uuid)sourcequery optionalstring (uuid)cursorquery optionalstringlimitquery optionalinteger (int32)orderquery optionalstring"asc"(the default — oldest first) or"desc"(newest first). Anything else is a 400 rather than a silent fallback to the default. A cursor is only valid against the order it was minted under, so do not changeordermid-walk.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/log/entries"POST /v1/research/log/negative-evidence Preview
Record a negative-evidence research-log entry
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/log/negative-evidence"GET /v1/research/log/{id} Preview
Get a research-log entry
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/log/{id}"POST /v1/research/log/{id}/details Preview
Append detail to a research-log entry
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/log/{id}/details"POST /v1/research/log/{id}/retract Preview
Retract a research-log entry from active views
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/log/{id}/retract"PUT /v1/research/log/{id}/text Preview
Correct a research-log entry's text
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/log/{id}/text"DELETE /v1/research/plan-items/{id} Preview
Delete a research plan item
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X DELETE \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/plan-items/{id}"PUT /v1/research/plan-items/{id}/description Preview
Correct a research plan item's description
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/plan-items/{id}/description"PUT /v1/research/plan-items/{id}/done Preview
Mark a research plan item done
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/plan-items/{id}/done"POST /v1/research/plan-items/{id}/reorder Preview
Reorder a research plan item
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/plan-items/{id}/reorder"GET /v1/research/questions Preview
List research questions, paginated
Parameters
statusquery optionalstring"open"/"closed".subject_kindquery optionalstringsubject_idquery optionalstring (uuid)cursorquery optionalstringlimitquery optionalinteger (int32)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/questions"POST /v1/research/questions Preview
Open a new research question
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
200
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/questions"GET /v1/research/questions/{id} Preview
Get a research question by id
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/questions/{id}"POST /v1/research/questions/{id}/close Preview
Close a research question
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (optional)
CloseQuestionRequestExample
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/questions/{id}/close"GET /v1/research/questions/{id}/coverage Preview
Get a research question's coverage status
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/questions/{id}/coverage"POST /v1/research/questions/{id}/coverage-confirm Preview
Confirm reasonably-exhaustive search coverage
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/questions/{id}/coverage-confirm"GET /v1/research/questions/{id}/plan Preview
Get a research question's plan
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/questions/{id}/plan"POST /v1/research/questions/{id}/plan/items Preview
Add an item to a research question's plan
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/questions/{id}/plan/items"POST /v1/research/questions/{id}/reopen Preview
Reopen a retired research question (human-only)
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/questions/{id}/reopen"PUT /v1/research/questions/{id}/subjects Preview
Set a research question's subject persons
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/questions/{id}/subjects"PUT /v1/research/questions/{id}/text Preview
Correct a research question's text
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/questions/{id}/text"POST /v1/research/sessions Preview
Start a research session under a question
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/sessions"POST /v1/research/sessions/{id}/end Preview
End a research session
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
200
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/research/sessions/{id}/end"GET /v1/settled Preview
Settled knowledge and retired leads, in one call
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/settled"GET /v1/trees/{tree_id}/project/state Preview
The session brief — current investigation state as a bounded digest
Parameters
sincequery optionalstringThe
cursorvalue from a previous brief; restricts every section to what changed after it. Omit for the full digest.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/project/state"GET /v1/trees/{tree_id}/research/log Preview
Get the research log for a session
Parameters
questionrequiredquerystring (uuid)
Responses
200
stringExample
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/log"POST /v1/trees/{tree_id}/research/log Preview
Add a search/source entry to the research log
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
200
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/log"POST /v1/trees/{tree_id}/research/log/capture Preview
Capture a research-log entry with evidence
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/log/capture"GET /v1/trees/{tree_id}/research/log/entries Preview
List research-log entries
Parameters
questionquery optionalstring (uuid)sessionquery optionalstring (uuid)personaquery optionalstring (uuid)sourcequery optionalstring (uuid)cursorquery optionalstringlimitquery optionalinteger (int32)orderquery optionalstring"asc"(the default — oldest first) or"desc"(newest first). Anything else is a 400 rather than a silent fallback to the default. A cursor is only valid against the order it was minted under, so do not changeordermid-walk.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/log/entries"POST /v1/trees/{tree_id}/research/log/negative-evidence Preview
Record a negative-evidence research-log entry
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/log/negative-evidence"GET /v1/trees/{tree_id}/research/log/{id} Preview
Get a research-log entry
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/log/{id}"POST /v1/trees/{tree_id}/research/log/{id}/details Preview
Append detail to a research-log entry
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/log/{id}/details"POST /v1/trees/{tree_id}/research/log/{id}/retract Preview
Retract a research-log entry from active views
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/log/{id}/retract"PUT /v1/trees/{tree_id}/research/log/{id}/text Preview
Correct a research-log entry's text
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/log/{id}/text"DELETE /v1/trees/{tree_id}/research/plan-items/{id} Preview
Delete a research plan item
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X DELETE \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/plan-items/{id}"PUT /v1/trees/{tree_id}/research/plan-items/{id}/description Preview
Correct a research plan item's description
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/plan-items/{id}/description"PUT /v1/trees/{tree_id}/research/plan-items/{id}/done Preview
Mark a research plan item done
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/plan-items/{id}/done"POST /v1/trees/{tree_id}/research/plan-items/{id}/reorder Preview
Reorder a research plan item
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/plan-items/{id}/reorder"GET /v1/trees/{tree_id}/research/questions Preview
List research questions, paginated
Parameters
statusquery optionalstring"open"/"closed".subject_kindquery optionalstringsubject_idquery optionalstring (uuid)cursorquery optionalstringlimitquery optionalinteger (int32)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/questions"POST /v1/trees/{tree_id}/research/questions Preview
Open a new research question
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
200
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/questions"GET /v1/trees/{tree_id}/research/questions/{id} Preview
Get a research question by id
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/questions/{id}"POST /v1/trees/{tree_id}/research/questions/{id}/close Preview
Close a research question
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (optional)
CloseQuestionRequestExample
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/questions/{id}/close"GET /v1/trees/{tree_id}/research/questions/{id}/coverage Preview
Get a research question's coverage status
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/questions/{id}/coverage"POST /v1/trees/{tree_id}/research/questions/{id}/coverage-confirm Preview
Confirm reasonably-exhaustive search coverage
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/questions/{id}/coverage-confirm"GET /v1/trees/{tree_id}/research/questions/{id}/plan Preview
Get a research question's plan
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/questions/{id}/plan"POST /v1/trees/{tree_id}/research/questions/{id}/plan/items Preview
Add an item to a research question's plan
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/questions/{id}/plan/items"POST /v1/trees/{tree_id}/research/questions/{id}/reopen Preview
Reopen a retired research question (human-only)
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/questions/{id}/reopen"PUT /v1/trees/{tree_id}/research/questions/{id}/subjects Preview
Set a research question's subject persons
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/questions/{id}/subjects"PUT /v1/trees/{tree_id}/research/questions/{id}/text Preview
Correct a research question's text
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/questions/{id}/text"POST /v1/trees/{tree_id}/research/sessions Preview
Start a research session under a question
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/sessions"POST /v1/trees/{tree_id}/research/sessions/{id}/end Preview
End a research session
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
200
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/research/sessions/{id}/end"GET /v1/trees/{tree_id}/settled Preview
Settled knowledge and retired leads, in one call
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/settled"GET /v1/assignments/{id} Preview
Get a recorded assignment by id
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/assignments/{id}"GET /v1/sessions/current Preview
Get the calling connection's current session, if any
Responses
200
SessionSummaryDtoExample
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/sessions/current"GET /v1/sessions/{id} Preview
Get a store session's summary by id
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/sessions/{id}"GET /v1/trees/{tree_id}/assignments/{id} Preview
Get a recorded assignment by id
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/assignments/{id}"GET /v1/trees/{tree_id}/sessions/current Preview
Get the calling connection's current session, if any
Responses
200
SessionSummaryDtoExample
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/sessions/current"GET /v1/trees/{tree_id}/sessions/{id} Preview
Get a store session's summary by id
Parameters
idrequiredpathstring (uuid)
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/sessions/{id}"GET /v1/sources Preview
List sources, paginated
Every source in the tree, cursor-paginated, with q= filtering on the
title. These rows are deliberately light — fetch
GET /v1/sources/{id} for a source's citation and full detail, and
GET /v1/sources/{id}/cited-by for the claims resting on it.
Parameters
qquery optionalstringCase-insensitive substring match on the source title. Applied before pagination, so
totalcounts the matches and page 2 of a filtered list is page 2 of the matches. This is a plain substring match, not the relevance-ranked searchGET /v1/persons?q=runs. Absent or blank ⇒ unfiltered.limitquery optionalinteger (int32)How many rows to return. Clamped to
1..=500; defaults to 100 when absent. A value outside the range is clamped, not rejected.cursorquery optionalstringThe
next_cursorfrom the previous page. Omit it for the first page. Treat it as opaque, and keep every other query parameter identical while walking — a cursor is only valid against the query that minted it.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/sources"POST /v1/sources Preview
Create a source
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
200
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/sources"POST /v1/sources/from-template Preview
Create a source from a citation template
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/sources/from-template"GET /v1/sources/{id} Preview
Get a source by id
Parameters
idrequiredpathstring (uuid)
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/sources/{id}"POST /v1/sources/{id}/attach-blob Preview
Attach an existing blob to a source
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/sources/{id}/attach-blob"GET /v1/sources/{id}/cited-by Preview
List the claims that cite a source, paginated
The inverse of the citation edge every assertion carries: given a
source, which claims rest on it. This is what turns the claim_count
on a source into something you can actually enumerate — unlike
GET /v1/assertions, it needs no persona to start from.
Always paginated: a source created by a GEDCOM import can carry
thousands of claims.
Parameters
idrequiredpathstring (uuid)limitquery optionalinteger (int32)How many rows to return. Clamped to
1..=500; defaults to 100 when absent. A value outside the range is clamped, not rejected.cursorquery optionalstringThe
next_cursorfrom the previous page. Omit it for the first page. Treat it as opaque, and keep every other query parameter identical while walking — a cursor is only valid against the query that minted it.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/sources/{id}/cited-by"GET /v1/trees/{tree_id}/sources Preview
List sources, paginated
Every source in the tree, cursor-paginated, with q= filtering on the
title. These rows are deliberately light — fetch
GET /v1/sources/{id} for a source's citation and full detail, and
GET /v1/sources/{id}/cited-by for the claims resting on it.
Parameters
qquery optionalstringCase-insensitive substring match on the source title. Applied before pagination, so
totalcounts the matches and page 2 of a filtered list is page 2 of the matches. This is a plain substring match, not the relevance-ranked searchGET /v1/persons?q=runs. Absent or blank ⇒ unfiltered.limitquery optionalinteger (int32)How many rows to return. Clamped to
1..=500; defaults to 100 when absent. A value outside the range is clamped, not rejected.cursorquery optionalstringThe
next_cursorfrom the previous page. Omit it for the first page. Treat it as opaque, and keep every other query parameter identical while walking — a cursor is only valid against the query that minted it.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/sources"POST /v1/trees/{tree_id}/sources Preview
Create a source
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
200
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/sources"POST /v1/trees/{tree_id}/sources/from-template Preview
Create a source from a citation template
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/sources/from-template"GET /v1/trees/{tree_id}/sources/{id} Preview
Get a source by id
Parameters
idrequiredpathstring (uuid)
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/sources/{id}"POST /v1/trees/{tree_id}/sources/{id}/attach-blob Preview
Attach an existing blob to a source
Parameters
idrequiredpathstring (uuid)idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/sources/{id}/attach-blob"GET /v1/trees/{tree_id}/sources/{id}/cited-by Preview
List the claims that cite a source, paginated
The inverse of the citation edge every assertion carries: given a
source, which claims rest on it. This is what turns the claim_count
on a source into something you can actually enumerate — unlike
GET /v1/assertions, it needs no persona to start from.
Always paginated: a source created by a GEDCOM import can carry
thousands of claims.
Parameters
idrequiredpathstring (uuid)limitquery optionalinteger (int32)How many rows to return. Clamped to
1..=500; defaults to 100 when absent. A value outside the range is clamped, not rejected.cursorquery optionalstringThe
next_cursorfrom the previous page. Omit it for the first page. Treat it as opaque, and keep every other query parameter identical while walking — a cursor is only valid against the query that minted it.
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/sources/{id}/cited-by"GET /v1/telemetry/config Preview
Get the telemetry export consent/config record
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/telemetry/config"PUT /v1/telemetry/config Preview
Set the telemetry export consent/config record
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
PutTelemetryConfigRequest
disclosure_acknowledgedoptionalbooleanexport_enabledoptionalboolean
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/telemetry/config"POST /v1/telemetry/events Preview
Record a telemetry event
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
PostTelemetryEventRequest
eventrequiredanyseqrequiredinteger (int32)session_idrequiredstring (uuid)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/telemetry/events"DELETE /v1/telemetry/queue Preview
Purge the local telemetry queue
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
200
TelemetryQueuePurgedDto
purgedrequiredboolean
Example
curl -sS -X DELETE \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/telemetry/queue"GET /v1/telemetry/queue Preview
Get the local telemetry queue
Responses
200 — newline-delimited JSON: the raw queued + pending-segment telemetry Envelope records, oldest-first
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/telemetry/queue"GET /v1/stats Preview
Whole-tree orientation statistics
Parameters
top_surnamesquery optionalinteger (int32)Surname-frequency list cap (default 10, max 50).
Responses
200
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/stats"GET /v1/trees Preview
List trees in this store
Parameters
include_archivedquery optionalboolean
Responses
200
TreeDtoExample
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees"POST /v1/trees Preview
Create a new tree
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
CreateTreeRequest
namerequiredstring
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees"GET /v1/trees/active Preview
Get the currently active tree
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/active"PUT /v1/trees/active Preview
Set the currently active tree
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
SetActiveTreeRequest
tree_idrequiredstring
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/active"POST /v1/trees/claim Preview
Name the tree a first-run reader starts in
The daemon boots with a provisional tree whose name no reader may see, so onboarding claims it rather than leaving an unexplained spare behind. But that tree is reachable by every other route while the blocking dialog sits open — the dialog's own copy invites a connected assistant to start researching — and a tree that has acquired a family line is no longer provisional. Deciding claim-vs-create in the caller means re-deciding it in every future caller; deciding it here means the answer cannot go stale between the decision and the write. The returned tree is made active: this is the tree the reader was told they now have, so it is the one they must be in.
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
ClaimTreeRequest
namerequiredstringprovisional_tree_idrequiredstring
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/claim"GET /v1/trees/{tree_id} Preview
Get a tree by id
Parameters
tree_idrequiredpathstring
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}"PATCH /v1/trees/{tree_id} Preview
Rename or archive/unarchive a tree
Parameters
tree_idrequiredpathstringidempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
PatchTreeRequest
archivedoptionalbooleannameoptionalstring
Example
curl -sS -X PATCH \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}"POST /v1/trees/{tree_id}/backup Preview
Back up a tree to the configured location (async)
Backs up a tree to the location configured for this installation.
Either actor class may call it — backing up is never destructive.
There is no request body and no destination parameter. A backup
always writes to the one location set through the human-only
PUT /v1/backup/config. That is deliberate: a per-call destination
would turn this into a "write bytes to any path I name" primitive
reachable with an agent credential. If no location is configured the
route refuses with 409 rather than choosing one.
Asynchronous. 404 (unknown tree) and 409 (no location
configured, or backups disabled) are synchronous refusals; otherwise
the copy runs as a job and the route returns 202 with a job_id.
Poll GET /v1/jobs/{job_id} or watch job.progress events; the
phases are staging, applying, finalizing. Once the backup
commits, older backups beyond the configured retention are pruned; a
prune that fails is logged and does not fail the backup.
Parameters
tree_idrequiredpathstringidempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/backup"POST /v1/trees/{tree_id}/delete Preview
Permanently delete a tree (async)
Deletes a whole tree — its history, its stored files and every
snapshot of it. Requires the human token: an agent credential can archive a
tree (which is reversible) but can never delete one.
Asynchronous. A tree can hold tens of thousands of records, so the
work runs as a job. Validation is synchronous — 404 for an unknown
tree, 409 if it is the active tree (switch away first) — and on
success the route returns 202 with a job_id. Poll
GET /v1/jobs/{job_id} for progress, or watch job.progress events
on the SSE stream; the phases are closing then removing. The job
re-validates before it runs, so a tree that became active in the
meantime fails the job rather than being deleted anyway.
Deletion is recoverable for a window: the tree's directory is moved to
a trash area rather than destroyed in place, and trash entries are
purged 30 days later.
Parameters
tree_idrequiredpathstringidempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/delete"GET /v1/trees/{tree_id}/home-person Preview
Get a tree's home person (the pedigree's default anchor)
Parameters
tree_idrequiredpathstring
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/home-person"PUT /v1/trees/{tree_id}/home-person Preview
Set or clear a tree's home person
Parameters
tree_idrequiredpathstringidempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/home-person"GET /v1/trees/{tree_id}/root-suggestions Preview
Suggest people this tree's pedigree could start from
Parameters
tree_idrequiredpathstring
Responses
200
RootSuggestionsDto
person_countrequiredinteger (int64)suggestionsrequiredarray ofRootSuggestionDto
ancestorsrequiredinteger (int32)birth_dateoptionalobjectdeath_dateoptionalobjectgenerationsrequiredinteger (int32)namerequiredstringpersonrequiredstring (uuid)
404
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/root-suggestions"GET /v1/trees/{tree_id}/stats Preview
Whole-tree orientation statistics
Parameters
top_surnamesquery optionalinteger (int32)Surname-frequency list cap (default 10, max 50).
Responses
200
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/stats"POST /v1/trees/{tree_id}/undo Preview
Undo the target edit, or the most recent undoable human edit
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/undo"GET /v1/trees/{tree_id}/undo/status Preview
The caller's last edit and what a no-target undo would target
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/trees/{tree_id}/undo/status"POST /v1/undo Preview
Undo the target edit, or the most recent undoable human edit
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/undo"GET /v1/undo/status Preview
The caller's last edit and what a no-target undo would target
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/undo/status"POST /v1/shutdown Experimental
Shut down the background service
Stops the background service. Requires the human token — an agent
credential can never call it.
Returns 204 immediately and then shuts down gracefully: in-flight
jobs are stopped at their own checkpoints and pending work is flushed
before the process exits, so a shutdown during an import does not lose
buffered records. Nothing asks the user to confirm; the caller is
expected to have done that. Once the process is gone its discovery
file is gone too, so a client rediscovers the service on next start.
Tier: experimental — this is a local control-plane route for the
app's own shell. It may change or disappear; do not build a third-party
integration on it.
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/shutdown"POST /v1/update/check Preview
Check for an available update
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
202 — check started; observe via status/SSE
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/update/check"POST /v1/update/restart Preview
Restart to apply a downloaded update
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Responses
Example
curl -sS -X POST \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/update/restart"GET /v1/update/settings Preview
Get the auto-updater's settings
Responses
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/update/settings"PUT /v1/update/settings Preview
Set the auto-updater's settings
Parameters
idempotency-keyheaderstring (idempotency-key)Reserved for future request deduplication. Not deduplicated today — the key is accepted and shape-validated (200 characters maximum, printable non-whitespace ASCII, or the request is rejected), but a retried request carrying the same key applies a second time. Do not rely on it for at-most-once delivery yet. It exists now so that real deduplication can be turned on later without changing this API.
Request body (required)
Responses
Example
curl -sS -X PUT \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ ... }' \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/update/settings"GET /v1/update/status Preview
Get the auto-updater's current status
Responses
200
UpdateStatusDto
available_versionoptionalstringchannelrequiredstringcurrent_versionrequiredstringerroroptionalstringerror_kindoptionalstringlast_check_atoptionalinteger (int64)noticeoptionalstringstaged_versionoptionalstringstaterequiredstring
Example
curl -sS -X GET \
-H "Authorization: Bearer $HEARTWOOD_TOKEN" \
"http://127.0.0.1:$HEARTWOOD_PORT/v1/update/status"Shared schemas139
AcceptedJobDto
job_idrequiredstring (uuid)
ActiveTreeDto
tree_idrequiredstring
AddLogEntryRequest
search_contextrequiredstringsessionrequiredstring (uuid)
AddNoteRequest
anchorsarray ofNoteAnchorDto (tagged union)
kind=assertionidrequiredstring (uuid)kindrequiredstring [enum: assertion]
kind=citationidrequiredstring (uuid)kindrequiredstring [enum: citation]
kind=life_eventidrequiredstring (uuid)kindrequiredstring [enum: life_event]
kind=personidrequiredstring (uuid)kindrequiredstring [enum: person]
kind=personaidrequiredstring (uuid)kindrequiredstring [enum: persona]
kind=sourceidrequiredstring (uuid)kindrequiredstring [enum: source]
citationsarray ofstring (uuid)textrequiredstring
AddParticipantRequest
attachedarray of(object, no properties)
evidence_classoptionalobjectpersonarequiredstring (uuid)research_search_contextrequiredstringresearch_sessionrequiredstring (uuid)rolerequired(object, no properties)
sourcerequiredstring (uuid)
ApproveRequest
summary_shownoptionalstring
AssertionDto
claimrequiredstringcreated_at_msrequiredinteger (int64)dispositionoptionalstringevent_contextoptionalEventContextDtoevidencerequired array ofEvidenceViewfabricatedrequiredbooleanfact_kindoptionalstringidrequiredstring (uuid)kindrequiredstringnameoptionalstringpersonarequiredstring (uuid)proposeroptionalstringrequested_byrequiredstringsourcerequiredstring (uuid)statusrequiredstring
AssignmentDto
contentrequiredAssignmentContentDto (tagged union)
kind=rawkindrequiredstring [enum: raw]textrequiredstring
kind=structuredargumentsrequired map: string →stringkindrequiredstring [enum: structured]prompt_namerequiredstring
idrequiredstring (uuid)recorded_at_msrequiredinteger (int64)
AssociationIdDto
assertion_idrequiredstring (uuid)
AttachEvidenceRequest
evidencerequired(object, no properties)
AttachSourceBlobRequest
blobrequiredstring
BackupConfigDto
backup_root_pathoptionalstringcadence_hoursrequiredinteger (int32)enabledrequiredbooleanretentionrequiredBackupRetentionDto
BackupRetentionDto
dailyrequiredinteger (int32)monthlyrequiredinteger (int32)weeklyrequiredinteger (int32)
BlobRefDto
blobrequiredstring
BulkConfirmRequest
assertion_idsrequired array ofstring (uuid)batch_noteoptionalstring
BulkConfirmResponseDto
batch_idrequiredstring (uuid)confirmedrequired array ofstring (uuid)duration_msrequiredinteger (int64)failedrequiredarray ofBulkConfirmFailureDto
idrequiredstring (uuid)reasonrequiredstring
CaptureRequest
claimrequiredstringfact_kindanypersonarequiredstring (uuid)research_search_contextrequiredstringresearch_sessionrequiredstring (uuid)sourcerequiredstring (uuid)
ChecklistViewDto
analysis_correlationrequiredbooleancomplete_citationsrequiredbooleanconflict_resolutionrequiredbooleanexhaustive_searchrequiredExhaustiveSearchStatusDto (tagged union)
status=claimablestatusrequiredstring [enum: claimable]
status=in_progresscoveredrequiredinteger (int32)statusrequiredstring [enum: in_progress]totalrequiredinteger (int32)
status=not_startedstatusrequiredstring [enum: not_started]
written_conclusionrequiredboolean
CitationRenderRequest
citation_idoptionalstring (uuid)elementsmap: string →stringformoptionalstringtemplate_idoptionalstring
CitationRenderResultDto
bibliographyoptionalRenderedTextDtocsloptionalobjectfirstoptionalRenderedTextDtosubsequentoptionalRenderedTextDtowarningsrequired array ofstring
CitationTemplatesListDto
registry_versionrequiredinteger (int32)templatesrequiredarray ofCitationTemplateDto
categoryrequiredstringfieldsrequiredarray ofCitationTemplateFieldDto
elementrequiredstringidrequiredstringlabelrequiredstringrequiredrequiredboolean
idrequiredstringlabelrequiredstring
ClaimTranscriptionRequest
claimrequiredstringof_blobrequiredstringpersonarequiredstring (uuid)regionoptionalRegionDto
heightrequirednumber (double)widthrequirednumber (double)xrequirednumber (double)yrequirednumber (double)
research_search_contextrequiredstringresearch_sessionrequiredstring (uuid)sourcerequiredstring (uuid)
CloseQuestionRequest
dispositionoptionalstringreasonoptionalstring
ConflictClaimDto
assertionrequiredstring (uuid)claimrequiredstringeventoptionalConflictClaimEventDto
dateoptionalobjectdate_phraseoptionalstringevent_idrequiredstring (uuid)kindrequired(object, no properties)
kind_phraseoptionalstringplaceoptionalobjectrolerequired(object, no properties)
fabricatedrequiredbooleanfact_kindoptionalstringhas_evidencerequiredbooleanis_confirmablerequiredbooleankindrequiredstringpersonarequiredstring (uuid)sourcerequiredstring (uuid)source_titleoptionalstringstatusrequiredstring
ConflictDto
assertionsrequired array ofstring (uuid)claimsrequired array ofConflictClaimDtoidrequiredstring (uuid)openrequiredbooleanscoperequiredConflictScopeDto
ConflictScopeDto
layer = identity
layerrequiredstring [enum: identity]personrequiredstring (uuid)
layer = persona
layerrequiredstring [enum: persona]personarequiredstring (uuid)
CorrectEventRequest
evidencearray of(object, no properties)
fieldrequiredstringkind_phraseoptionalstringsource_idrequiredstring (uuid)valuerequired(object, no properties)
CorrectionResultDto
appliedrequiredbooleanproposal_idoptionalstring (uuid)
CreateCitationRequest
elementsrequiredarray of(object, no properties)
CreateCitationResultDto
idrequiredstring (uuid)
CreatePersonaRequest
labelrequiredstringsourcerequiredstring (uuid)
CreatePersonRequest
certaintyrequired(object, no properties)
personasrequired array ofstring (uuid)proof_argumentoptionalstring (uuid)
CreatePersonResultDto
appliedrequiredbooleanidoptionalstring (uuid)proposal_idoptionalstring (uuid)
CreateSourceRequest
titlerequiredstring
DenyRequest
reasonrequiredstring
DuplicateCandidateDto
birth_yearoptionalinteger (int32)death_yearoptionalinteger (int32)idrequiredstring (uuid)likelihoodrequiredstringnamerequiredstringscore_permillerequiredinteger (int32)
EntityLabelDto
idrequiredstring (uuid)kindrequiredstringlabelrequiredstring
EventContextDto
dateoptionalobjectevent_idrequiredstring (uuid)kindrequired(object, no properties)
kind_phraseoptionalstringplaceoptionalobjectsibling_participationsrequiredarray ofSiblingParticipationDto
persona_idrequiredstring (uuid)persona_label_idrequiredstringrolerequired(object, no properties)
statusrequiredstring
source_idrequiredstring (uuid)
EvidenceView
kind = external_record
kindrequiredstring [enum: external_record]recordrequiredExternalRecordIdView (tagged union)
kind=ancestry_recorddbidrequiredstringkindrequiredstring [enum: ancestry_record]recordrequiredstring
kind=doidoirequiredstringkindrequiredstring [enum: doi]
kind=family_search_arkarkrequiredstringkindrequiredstring [enum: family_search_ark]
kind=permalinkkindrequiredstring [enum: permalink]urlrequiredstring
kind = offline_record
citationrequiredstringkindrequiredstring [enum: offline_record]
kind = source_blob
content_addressrequiredstringkindrequiredstring [enum: source_blob]
FanNetworkDto
neighborsrequiredarray ofFanNeighborDto
edgesrequiredarray ofFanEdgeDto
assertionoptionalstring (uuid)eventoptionalstring (uuid)own_eventoptionalstring (uuid)own_roleoptionalstringplace_idoptionalstringrelationoptionalobjecttheir_eventoptionalstring (uuid)their_roleoptionalstringtyperequiredstring
personoptionalstring (uuid)personarequiredstring (uuid)
GedcomExportRequest
destinationoptionalstringgedcom_versionrequiredstringinclude_livingbooleanoverwriteboolean
GedcomExportResultDto
appliedrequiredbooleanbloboptionalstringfileoptionalstringloss_report_idoptionalstring (uuid)messagerequiredstringproposal_idoptionalstring (uuid)sha256optionalstring
HomePersonDto
home_personoptionalstring (uuid)
ImportRecordDto
assertionsrequiredinteger (int32)at_msrequiredinteger (int64)file_nameoptionalstringimport_keyrequiredstringin_treerequiredImportContentsDto
assertionsrequiredinteger (int32)citationsrequiredinteger (int32)life_eventsrequiredinteger (int32)mediarequiredinteger (int32)notesrequiredinteger (int32)otherrequiredinteger (int32)personasrequiredinteger (int32)sourcesrequiredinteger (int32)totalrequiredinteger (int32)
personasrequiredinteger (int32)raw_filerequiredstringstatusrequiredstringundonerequiredboolean
JobDto
created_at_msrequiredinteger (int64)idrequiredstring (uuid)kindrequiredstringpercentoptionalinteger (int32)reasonoptionalstringstatusrequiredstringsummaryoptionalstringtree_idrequiredstringupdated_at_msrequiredinteger (int64)
LifeEventDto
dateoptionalobjectdate_phraseoptionalstringidrequiredstring (uuid)kindrequired(object, no properties)
kind_phraseoptionalstringparticipationsrequiredarray ofParticipantViewDto
assertionrequiredstring (uuid)personarequiredstring (uuid)persona_labelrequiredstringrolerequired(object, no properties)
statusrequiredstring
placeoptionalobjectsourcerequiredstring (uuid)source_titlerequiredstring
LogDetailAppendRequest
detailrequiredstring
LogDetailAppendResponseDto
log_entry_idrequiredstring (uuid)
LogDetailDto
attestationrequiredstringdetailrequiredstringidrequiredstring (uuid)recorded_atrequiredinteger (int64)
LogEntryTextSetRequest
search_contextrequiredstring
LogNegativeRecordRequest
expectationrequiredstringinferencerequiredstringlog_entryrequiredstring (uuid)personarequiredstring (uuid)
LogNegativeRecordResponseDto
negative_evidence_idrequiredstring (uuid)
LossReportDto
created_at_msrequiredinteger (int64)directionrequiredstringentriesrequiredarray ofLossEntryDto
categoryrequiredstringcoderequiredstringcountrequiredinteger (int32)detailrequiredstringrecord_refsarray ofstringscoperequiredstringtag_pathrequiredstring
filerequiredLossReportFileInfoDto
bloboptionalstringcompletenessrequiredstringnamerequiredstringsha256requiredstring
gedcom_versionrequiredstringreport_idrequiredstring (uuid)schema_versionrequiredinteger (int32)totalsrequiredLossReportTotalsDto
entry_countrequiredinteger (int32)losslessrequiredbooleanrecords_droppedoptionalinteger (int32)records_mappedoptionalinteger (int32)records_seenoptionalinteger (int32)structures_emittedoptionalinteger (int32)structures_visitedoptionalinteger (int32)
MediaResolveResultDto
blobrequiredstringbyte_lenrequiredinteger (int64)statusrequiredstring
MergePersonsRequest
leftrequiredstring (uuid)rightrequiredstring (uuid)
MergePersonsResultDto
idrequiredstring (uuid)
NoteDto
citationsrequired array ofstring (uuid)idrequiredstring (uuid)requested_byrequiredstringtextrequiredstring
NoteIdDto
note_idrequiredstring (uuid)
OkResponseDto
okrequiredboolean
OpenResearchQuestionRequest
questionrequiredstring
Page_AssertionDto
itemsrequiredarray ofclaimrequiredstringcreated_at_msrequiredinteger (int64)dispositionoptionalstringevent_contextoptionalEventContextDtoevidencerequired array ofEvidenceViewfabricatedrequiredbooleanfact_kindoptionalstringidrequiredstring (uuid)kindrequiredstringnameoptionalstringpersonarequiredstring (uuid)proposeroptionalstringrequested_byrequiredstringsourcerequiredstring (uuid)statusrequiredstring
next_cursoroptionalstringtotalrequiredinteger
Page_AuditEntryDto
itemsrequiredarray ofactorrequiredstringactor_modeloptionalstringactor_reported_harnessoptionalstringactor_sessionoptionalstring (uuid)at_msrequiredinteger (int64)changesarray ofAuditChangeDto
fieldrequiredstringvaluerequiredstring
event_typerequiredstringidrequiredstring (uuid)kindrequiredstring [enum: change, session_record]payloadanysubjectoptionalAuditSubjectDto
idrequiredstring (uuid)kindrequiredstring
viaoptionalstring
next_cursoroptionalstringtotalrequiredinteger
Page_ConflictDto
itemsrequiredarray ofassertionsrequired array ofstring (uuid)claimsrequired array ofConflictClaimDtoidrequiredstring (uuid)openrequiredbooleanscoperequiredConflictScopeDto
next_cursoroptionalstringtotalrequiredinteger
Page_JobDto
itemsrequiredarray ofcreated_at_msrequiredinteger (int64)idrequiredstring (uuid)kindrequiredstringpercentoptionalinteger (int32)reasonoptionalstringstatusrequiredstringsummaryoptionalstringtree_idrequiredstringupdated_at_msrequiredinteger (int64)
next_cursoroptionalstringtotalrequiredinteger
Page_PersonDto
itemsrequiredarray ofbirth_dateoptionalobjectcertaintyrequiredstringdeath_dateoptionalobjectidrequiredstring (uuid)namerequiredstringupdated_at_msrequiredinteger (int64)
next_cursoroptionalstringtotalrequiredinteger
Page_ProposalDto
itemsrequiredarray ofdestination_hintoptionalstringdetailsrequiredProposalDetailsDto (tagged union)
kind=conclude_personcertaintyrequiredstringkindrequiredstring [enum: conclude_person]personasrequired array ofstring (uuid)proof_argumentoptionalstring (uuid)
kind=correct_event_dateeventrequiredstring (uuid)kindrequiredstring [enum: correct_event_date]new_daterequired(object, no properties)
sourcerequiredstring (uuid)
kind=correct_event_kindeventrequiredstring (uuid)kindrequiredstring [enum: correct_event_kind]kind_phraseoptionalstringnew_kindrequired(object, no properties)
sourcerequiredstring (uuid)
kind=correct_event_placeeventrequiredstring (uuid)kindrequiredstring [enum: correct_event_place]new_placerequired(object, no properties)
sourcerequiredstring (uuid)
kind=export_everythingdestination_hintoptionalstringkindrequiredstring [enum: export_everything]
kind=export_gedcomdestination_hintoptionalstringgedcom_versionrequiredstringinclude_livingrequiredbooleankindrequiredstring [enum: export_gedcom]
kind=record_proof_argumentcertaintyrequiredstringclaims_exhaustive_searchrequiredbooleanconclusionrequiredstringcontraryrequired array ofstring (uuid)correlation_reasoningrequiredstringkindrequiredstring [enum: record_proof_argument]questionrequiredstring (uuid)supportingrequired array ofstring (uuid)
kind=redactkindrequiredstring [enum: redact]reasonrequiredstringtargetrequiredstring (uuid)
kind=set_citation_elementscitationrequiredstring (uuid)element_countrequiredinteger (int32)kindrequiredstring [enum: set_citation_elements]
kind=undo_gedcom_importimport_keyrequiredstringkindrequiredstring [enum: undo_gedcom_import]
idrequiredstring (uuid)kindrequiredstringreasonoptionalstringrequested_byrequiredstringstatusrequiredstringtargetoptionalstring (uuid)target_summaryoptionalstring
next_cursoroptionalstringtotalrequiredinteger
Page_SourceCitedClaimDto
itemsrequiredarray ofassertionrequiredstring (uuid)claimrequiredstringkindrequiredstringpersonoptionalstring (uuid)person_nameoptionalstringpersonarequiredstring (uuid)persona_labelrequiredstringstatusrequiredstring
next_cursoroptionalstringtotalrequiredinteger
Page_SourceListItemDto
itemsrequiredarray ofclaim_countrequiredintegerhas_citationrequiredbooleanidrequiredstring (uuid)titlerequiredstring
next_cursoroptionalstringtotalrequiredinteger
Page_UnsourcedAssertionDto
itemsrequiredarray ofassertionrequiredAssertionDtopersonoptionalstring (uuid)persona_labelrequiredstring
next_cursoroptionalstringtotalrequiredinteger
ParticipationIdDto
participation_idrequiredstring (uuid)
PedigreeDto
anchorrequiredstring (uuid)generationsrequiredinteger (int32)slotsrequiredarray ofPedigreeSlotDto
birth_dateoptionalobjectdeath_dateoptionalobjecthas_more_ancestorsrequiredbooleannamerequiredstringpersonrequiredstring (uuid)slotrequiredinteger (int64)
PendingPageDto
groupsoptional array ofPendingGroupDto
countrequiredinteger (int32)group_keyoptionalstringitemsrequired array ofAssertionDto
itemsrequired array ofAssertionDtonext_cursoroptionalstring
PersonaDto
concluded_personoptionalstring (uuid)idrequiredstring (uuid)labelrequiredstringperson_birth_dateoptionalobjectperson_death_dateoptionalobjectperson_nameoptionalstringsourcerequiredstring (uuid)
PersonCardDto
assertion_countrequiredinteger (int32)assertionsoptional array ofPersonCardAssertionDto
claimrequiredstringidrequiredstring (uuid)kindrequiredstringpersonarequiredstring (uuid)persona_labelrequiredstringsourcerequiredstring (uuid)source_titlerequiredstringstaterequiredstring
birth_yearoptionalinteger (int32)childrenrequired array ofPersonSummaryDtodeath_yearoptionalinteger (int32)eventsoptional array ofLifeEventDtoidrequiredstring (uuid)namerequiredstringparentsrequired array ofPersonSummaryDtosource_countrequiredinteger (int32)sourcesoptional array ofPersonCardSourceDto
has_citationrequiredbooleanidrequiredstring (uuid)titlerequiredstring
spousesrequired array ofPersonSummaryDto
PersonDetailDto
birth_dateoptionalobjectcertaintyrequiredstringdeath_dateoptionalobjectidrequiredstring (uuid)namerequiredstringpersonasrequired array ofstring (uuid)updated_at_msrequiredinteger (int64)
PersonSummaryDto
birth_yearoptionalinteger (int32)death_yearoptionalinteger (int32)idrequiredstring (uuid)namerequiredstring
PlanItemAddRequest
descriptionrequiredstringpositionoptionalinteger (int32)source_idoptionalstring (uuid)
PlanItemAddResponseDto
item_idrequiredstring (uuid)
PlanItemDescriptionSetRequest
descriptionrequiredstring
PlanItemDoneSetRequest
donerequiredboolean
PlanItemDoneSetResponseDto
donerequiredbooleanitemrequiredstring (uuid)
PlanItemReorderRequest
positionrequiredinteger (int32)
Problem
detailrequiredstringstatusrequiredinteger (int32)titlerequiredstringtyperequiredstring
ProofArgumentDto
certaintyrequiredstringclaims_exhaustive_searchrequiredbooleanconclusionrequiredstringcontrary_evidencerequiredarray ofContraryTreatmentView
assertionrequiredstring (uuid)treatmentrequiredstring
correlation_reasoningrequiredstringidrequiredstring (uuid)questionrequiredstring (uuid)supportingrequired array ofstring (uuid)
ProofArgumentExportDto
certaintyrequiredstringclaims_exhaustive_searchrequiredbooleangps_checklistrequiredChecklistViewDtoidrequiredstring (uuid)provenancerequiredExportProvenanceDto
at_msrequiredinteger (int64)creatorrequiredstringviaoptionalstring
questionrequiredExportQuestionDto
idrequiredstring (uuid)textrequiredstring
schemarequiredstringsectionsrequiredarray ofExportSectionDto
bodyrequiredstringcitationsrequiredarray ofExportCitationDto
assertion_idrequiredstring (uuid)citation_idrequiredstring (uuid)rendered_footnoterequiredstring
kindrequiredstring
ProofArgumentListResponseDto
itemsrequired array ofProofArgumentDtonext_cursoroptionalstring
ProposeRedactRequest
reasonrequiredstringtargetrequiredstring (uuid)
QuestionCoverageResponseDto
gpsrequiredChecklistViewDto
QuestionDto
idrequiredstring (uuid)questionrequiredstringstatusrequiredstringsubjectsrequired array ofSubjectRefDto
QuestionSubjectsSetRequest
subjectsrequired array ofSubjectRefDto
QuestionTextSetRequest
textrequiredstring
RecordAssociationRequest
attachedarray of(object, no properties)
evidence_classoptionalobjectotherrequiredstring (uuid)personarequiredstring (uuid)relationrequired(object, no properties)
research_search_contextrequiredstringresearch_sessionrequiredstring (uuid)sourcerequiredstring (uuid)
RecordedLifeEventDto
event_idrequiredstring (uuid)participation_idsrequired array ofstring (uuid)
RecordLifeEventRequest
dateoptionalobjectkindrequired(object, no properties)
kind_phraseoptionalstringparticipantsrequiredarray ofParticipantInputDto
attachedarray of(object, no properties)
evidence_classoptionalobjectpersonarequiredstring (uuid)rolerequired(object, no properties)
placeoptionalobjectresearch_search_contextrequiredstringresearch_sessionrequiredstring (uuid)sourcerequiredstring (uuid)
RecordProofArgumentRequest
certaintyrequired(object, no properties)
claims_exhaustive_searchrequiredbooleanconclusionrequiredstringcontrary_evidencerequired(object, no properties)
correlation_reasoningrequiredstringquestionrequiredstring (uuid)supportingrequired array ofstring (uuid)
RecordProofArgumentResultDto
appliedrequiredbooleanargumentoptionalProofArgumentDtoproposal_idoptionalstring (uuid)
RedactionRequest
reasonrequiredstringsummary_shownrequiredstringtargetrequiredstring (uuid)
RedactionResultDto
blobs_purgedrequiredintegerredactedrequiredboolean
RelationshipAttachRequest
kindrequiredstringpersonrequiredstring (uuid)relativerequiredstring (uuid)research_search_contextrequiredstringresearch_sessionrequiredstring (uuid)sourcerequiredstring (uuid)
RelationshipOutcomeDto
assertionsrequired array ofstring (uuid)createdrequiredbooleaneventrequiredstring (uuid)
RelationshipReparentRequest
childrequiredstring (uuid)from_parentrequiredstring (uuid)research_search_contextrequiredstringresearch_sessionrequiredstring (uuid)sourcerequiredstring (uuid)to_parentrequiredstring (uuid)
RelationshipUnlinkRequest
kindrequiredstringpersonrequiredstring (uuid)relativerequiredstring (uuid)research_search_contextrequiredstringresearch_sessionrequiredstring (uuid)
RenderedTextDto
htmlrequiredstringtextrequiredstring
ResearchLogCaptureRequest
found_nothingbooleanpersonaoptionalstring (uuid)questionoptionalstring (uuid)search_contextrequiredstringsessionoptionalstring (uuid)sourceoptionalstring (uuid)
ResearchLogCaptureResponseDto
linkedrequiredResearchLogCaptureLinkedDto
personaoptionalstring (uuid)plan_itemoptionalstring (uuid)sourceoptionalstring (uuid)
log_entry_idrequiredstring (uuid)session_idrequiredstring (uuid)
ResearchLogEntryDto
attestationrequiredstringdetailsrequired array ofLogDetailDtofound_nothingrequiredbooleanidrequiredstring (uuid)personaoptionalstring (uuid)plan_itemoptionalstring (uuid)questionoptionalstring (uuid)recorded_atrequiredinteger (int64)search_contextrequiredstringsessionrequiredstring (uuid)sourceoptionalstring (uuid)
ResearchLogListResponseDto
entriesrequiredarray ofResearchLogListEntryDto
attestationrequiredstringdetailsrequired array ofLogDetailDtofound_nothingrequiredbooleanidrequiredstring (uuid)personaoptionalstring (uuid)plan_itemoptionalstring (uuid)questionoptionalstring (uuid)recorded_atrequiredinteger (int64)search_contextrequiredstringsessionrequiredstring (uuid)sourceoptionalstring (uuid)
next_cursoroptionalstringtotalrequiredinteger
ResearchPlanGetResponseDto
coveragerequiredChecklistViewDtoitemsrequiredarray ofPlanItemDto
descriptionrequiredstringdonerequiredbooleanidrequiredstring (uuid)log_entry_countrequiredinteger (int32)positionrequiredinteger (int32)source_idoptionalstring (uuid)
ResearchQuestionDto
idrequiredstring (uuid)questionrequiredstring
ResearchQuestionListResponseDto
itemsrequired array ofQuestionDtonext_cursoroptionalstring
ResolveConflictRequest
proof_argumentrequiredstring (uuid)
ResolveMediaRequest
blobrequiredstring
SessionBriefDto
conflictsrequiredConflictDetectionBriefDto
conflicts_recordedrequiredintegerdetection_has_runrequiredbooleanimports_observedrequiredintegeropen_conflictsrequiredintegertriggerrequiredstring
cursorrequiredstringopen_questionsrequiredOpenQuestionsSectionDto
itemsrequiredarray ofOpenQuestionBriefDto
gpsrequiredChecklistViewDtoidrequiredstring (uuid)log_entriesrequiredintegerplan_itemsrequiredintegerquestionrequiredstringsubjectsrequiredinteger
totalrequiredinteger
pendingrequiredPendingLaneBriefDto
deferredrequiredintegerdepthrequiredinteger
retiredrequiredRetiredSectionDto
itemsrequiredarray ofRetiredLeadBriefDto
closed_at_msrequiredinteger (int64)dispositionoptionalstringidrequiredstring (uuid)questionrequiredstringreasonoptionalstring
totalrequiredinteger
rulesrequired array ofstringsettledrequiredSettledSectionDto
confirmed_assertionsrequiredConfirmedAssertionsSectionDto
itemsrequiredarray ofConfirmedAssertionBriefDto
claimrequiredstringidrequiredstring (uuid)
totalrequiredinteger
proof_argumentsrequiredProofArgumentsSectionDto
itemsrequiredarray ofProofArgumentBriefDto
certaintyrequiredstringconclusionrequiredstringidrequiredstring (uuid)questionrequiredstring (uuid)recorded_at_msrequiredinteger (int64)
totalrequiredinteger
sinceoptionalstring
SessionSummaryDto
actor_modeloptionalstringactor_reported_harnessoptionalstringcurrent_assignmentoptionalstring (uuid)event_countrequiredintegerfirst_seen_at_msrequiredinteger (int64)last_seen_at_msrequiredinteger (int64)sessionrequiredstring (uuid)
SetCitationElementsRequest
elementsrequired map: string →string
SetCitationElementsResultDto
appliedrequiredbooleanproposal_idoptionalstring (uuid)renderedoptionalCitationRenderResultDtorevisionoptionalinteger (int32)
SetCitationSourceTypeRequest
template_idrequiredstring
SetCitationSourceTypeResultDto
appliedrequiredbooleanmissing_requiredoptional array ofstringproposal_idoptionalstring (uuid)revisionoptionalinteger (int32)template_idoptionalstring
SetLivingStatusRequest
statusrequired(object, no properties)
SetNamePiecesRequest
piecesrequired(object, no properties)
research_search_contextrequiredstringresearch_sessionrequiredstring (uuid)
SettledKnowledgeDto
conclusionsrequiredarray ofSettledConclusionDto
certaintyrequiredstringconclusionrequiredstringidrequiredstring (uuid)questionrequiredstring (uuid)question_textrequiredstringrecorded_at_msrequiredinteger (int64)recorded_byrequiredstring
negative_findingsrequiredarray ofNegativeFindingDto
expectationrequiredstringinferencerequiredstringlog_entryrequiredstring (uuid)questionoptionalstring (uuid)recorded_at_msrequiredinteger (int64)recorded_byrequiredstringsearch_contextoptionalstring
refutationsrequiredarray ofRuledOutAssertionDto
claimrequiredstringidrequiredstring (uuid)ruled_out_at_msoptionalinteger (int64)ruled_out_byoptionalstringstatusrequiredstring
rejected_evidencerequiredarray ofRejectedEvidenceDto
assertionrequiredstring (uuid)proof_argumentrequiredstring (uuid)recorded_at_msrequiredinteger (int64)recorded_byrequiredstringtreatmentrequiredstring
retired_leadsrequiredarray ofRetiredLeadDto
closed_at_msrequiredinteger (int64)dispositionoptionalstringidrequiredstring (uuid)questionrequiredstringreasonoptionalstring
SourceDto
blobsrequired array ofstringcitationoptionalSourceCitationDto
bibliographyoptionalstringelementsrequiredarray ofCitationElementDto
kindrequiredstringlabeloptionalstringvaluerequiredstring
field_valuesmap: string →stringfinalized_proseoptionalstringfirstoptionalstringidrequiredstring (uuid)missing_requiredarray ofstringrevisionoptionalinteger (int32)subsequentoptionalstring
claim_countrequiredintegerderived_fromoptionalstring (uuid)idrequiredstring (uuid)titlerequiredstring
SourceFromTemplateRequest
elementsrequired map: string →stringtemplate_idrequiredstringtitleoptionalstring
SourceFromTemplateResultDto
citation_idrequiredstring (uuid)createdrequiredbooleanrenderedrequiredCitationRenderResultDtosource_idrequiredstring (uuid)
SourcingTallyDto
needs_sourcerequiredintegersourcedrequiredintegertotalrequiredinteger
SplitPersonRequest
leftrequired array ofstring (uuid)rightrequired array ofstring (uuid)
SplitPersonResultDto
leftrequiredstring (uuid)rightrequiredstring (uuid)
StartSessionRequest
questionrequiredstring (uuid)
SubjectRefDto
kind = life_event
idrequiredstring (uuid)kindrequiredstring [enum: life_event]
kind = person
idrequiredstring (uuid)kindrequiredstring [enum: person]
kind = persona
idrequiredstring (uuid)kindrequiredstring [enum: persona]
SupersedeAssertionRequest
byrequiredstring (uuid)
TelemetryConfigDto
acknowledged_schema_versionoptionalinteger (int32)backlog_purged_atoptionalstringdisclosure_acknowledgedrequiredbooleanexport_enabledrequiredbooleanlast_export_atoptionalstring
TreeDto
archivedrequiredbooleancreated_at_msrequiredinteger (int64)idrequiredstringlast_modified_at_msoptionalinteger (int64)locationoptionalstringnamerequiredstringperson_countoptionalinteger (int32)size_bytesoptionalinteger (int64)store_missingrequiredboolean
TreeStatsDto
birth_year_maxoptionalinteger (int32)birth_year_minoptionalinteger (int32)missing_birth_date_countrequiredinteger (int32)missing_death_date_countrequiredinteger (int32)person_countrequiredinteger (int32)read_onlyrequiredbooleanread_only_reasonsrequired array ofstringrefused_segmentsrequiredinteger (int32)source_countrequiredinteger (int32)top_surnamesrequiredarray ofSurnameCountDto
countrequiredinteger (int32)surnamerequiredstring
UndoImportRequest
summary_shownrequiredstring
UndoRequest
eventoptionalstring (uuid)
UndoResponse
compensatingrequired array ofstring (uuid)undonerequiredstring (uuid)undone_event_typerequiredstring
UndoStatusResponse
last_editoptionalEditDispositionDto
eventrequiredstring (uuid)event_typerequiredstringundoablerequiredUndoableNowDto
issueoptionalstringrationaleoptionalstringstaterequiredstring
targetoptionalUndoTargetDto
at_msrequiredinteger (int64)eventrequiredstring (uuid)event_typerequiredstring
UnresolvedMediaDto
file_namerequiredstringkindrequiredstringmedia_idrequiredstring (uuid)
UpdateSettingsDto
check_automaticallyrequiredboolean
Calling the API
The API is loopback-only: the daemon binds 127.0.0.1 on an
OS-assigned port (never a fixed one) and writes a discovery file,
discovery.json, into its data directory,
carrying that port and a bearer token. On macOS — the only platform
Heartwood ships today — that data directory is
~/Library/Application Support/com.twiglylabs.heartwood, so the full path is
~/Library/Application Support/com.twiglylabs.heartwood/discovery.json.
(A Windows build is planned but not available yet; there is no Windows
data-dir path to give until one ships.) Read the port and token from that
file, then send the token as a bearer credential on every request:
Authorization: Bearer <token from the discovery file>
The examples on each route on the Reference tab use
$HEARTWOOD_PORT and $HEARTWOOD_TOKEN for those
two values. Use the token from
discovery.json itself, not a "human-token"
file that may sit next to it — that second file is a separately minted
credential for the app's own UI only and will not authenticate a request
here.
Build a tool
Heartwood is closed source, but not a black box: this documented local surface — the same one the app's own AI features use — is yours to build on. Don't hand-write a client: point your coding agent at the docs below and describe the tool you want. Every request goes through one of two doors, both entirely local — nothing leaves your machine: this HTTP API, or a local MCP server exposing the same actions as tools an AI assistant can call directly (building "give my AI a new capability" rather than a standalone script? see Connect your AI instead).
Tool ideas worth having your agent build — concrete starting points, each realistic as a single agent session against this API: a photo tagger that walks a folder of scans and captures who's in each one as evidence; a research-log exporter that formats your open questions as a shareable write-up; a DNA-match cross-referencer that flags plausible connections against personas already in your tree; a census-batch capture helper that turns a spreadsheet of transcribed rows into properly cited assertions; a proof-argument formatter that lays out an exported proof argument as a submittable narrative document.
Paste this into your agent to get it oriented before it writes any code:
Read https://heartwood.family/llms.txt — it indexes every Heartwood doc
page (API reference, MCP reference, guides). For the full corpus in one
file, use https://heartwood.family/llms-full.txt instead. Then read the
"Calling the API" tab on this page for how to find and authenticate to
the running daemon, and use the per-resource docs linked from llms.txt
under docs/api/resources/ to write a small script that lists my open
research questions and prints a one-line summary of each. Once that
works end to end — discovering the daemon, authenticating, and calling
the route — we'll turn it into <the real tool you want>.
Every route, request/response shape, and the
application/problem+json error model is browsable on the
Reference tab of this page. The same content as per-resource markdown
your agent can read directly, without rendering HTML: API
reference index (markdown).