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.

Operation ID list_assertions

Parameters
  • personarequiredquery string (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 optional string

    Keep only assertions whose kind equals this string exactly (e.g. "fact") — the same vocabulary a returned assertion's kind uses.

  • statequery optional string

    Keep only assertions whose epistemic status equals this string exactly (e.g. "confirmed"). The parameter is spelled state; the field it filters is spelled status in the response body. Same vocabulary, different name.

  • sourcequery optional string (uuid)

    Keep only assertions whose source equals this source id.

  • sortquery optional string

    How to order the results. "created" — by the assertion's created_at_ms — is the only value accepted today; anything else is a 400. Absent ⇒ ordering by id.

  • orderquery optional string

    asc (default, oldest first) or desc (newest first). A cursor is only valid against the order it was minted under.

  • limitquery optional integer (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 optional string

    The next_cursor from 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

Operation ID capture_assertion

Parameters
  • idempotency-keyheader string (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

Operation ID post_transcription_claim

Parameters
  • idempotency-keyheader string (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

Operation ID list_unsourced_assertions

Parameters
  • limitquery optional integer (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 optional string

    The next_cursor from 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.

Operation ID tally_unsourced_assertions

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

Operation ID get_assertion

Parameters
  • idrequiredpath string (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

Operation ID attach_evidence

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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}/attach-evidence"

POST /v1/assertions/{id}/confirm Preview

Confirm a pending assertion

Operation ID confirm_assertion

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

403

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

Operation ID mark_fabricated

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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}/mark-fabricated"

POST /v1/assertions/{id}/refute Preview

Refute an assertion

Operation ID refute_assertion

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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}/refute"

POST /v1/assertions/{id}/supersede Preview

Supersede an assertion with a replacement

Operation ID post_assertion_supersede

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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.

Operation ID list_assertions

Parameters
  • personarequiredquery string (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 optional string

    Keep only assertions whose kind equals this string exactly (e.g. "fact") — the same vocabulary a returned assertion's kind uses.

  • statequery optional string

    Keep only assertions whose epistemic status equals this string exactly (e.g. "confirmed"). The parameter is spelled state; the field it filters is spelled status in the response body. Same vocabulary, different name.

  • sourcequery optional string (uuid)

    Keep only assertions whose source equals this source id.

  • sortquery optional string

    How to order the results. "created" — by the assertion's created_at_ms — is the only value accepted today; anything else is a 400. Absent ⇒ ordering by id.

  • orderquery optional string

    asc (default, oldest first) or desc (newest first). A cursor is only valid against the order it was minted under.

  • limitquery optional integer (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 optional string

    The next_cursor from 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

Operation ID capture_assertion

Parameters
  • idempotency-keyheader string (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

Operation ID post_transcription_claim

Parameters
  • idempotency-keyheader string (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

Operation ID list_unsourced_assertions

Parameters
  • limitquery optional integer (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 optional string

    The next_cursor from 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.

Operation ID tally_unsourced_assertions

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

Operation ID get_assertion

Parameters
  • idrequiredpath string (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

Operation ID attach_evidence

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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}/attach-evidence"

POST /v1/trees/{tree_id}/assertions/{id}/confirm Preview

Confirm a pending assertion

Operation ID confirm_assertion

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

403

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

Operation ID mark_fabricated

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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}/mark-fabricated"

POST /v1/trees/{tree_id}/assertions/{id}/refute Preview

Refute an assertion

Operation ID refute_assertion

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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}/refute"

POST /v1/trees/{tree_id}/assertions/{id}/supersede Preview

Supersede an assertion with a replacement

Operation ID post_assertion_supersede

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID post_association

Parameters
  • idempotency-keyheader string (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

Operation ID post_association

Parameters
  • idempotency-keyheader string (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

Operation ID get_audit

Parameters
  • includequery optional string

  • limitquery optional integer (int32)

  • cursorquery optional string

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

Operation ID get_audit

Parameters
  • includequery optional string

  • limitquery optional integer (int32)

  • cursorquery optional string

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

Operation ID get_backup_config

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

Operation ID put_backup_config

Parameters
  • idempotency-keyheader string (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_path optional string

  • cadence_hoursrequired integer (int32)

  • enabledrequired boolean

  • retentionrequired BackupRetentionDto

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.

Operation ID get_backup_manifests

Parameters
  • backup_rootrequiredquery string

Responses

200

BackupManifestsDto

  • manifestsrequired

    array of

    BackupManifestDto

    • app_version optional string

    • backup_idrequired string

    • created_at_ms optional integer (int64)

    • event_count optional integer (int64)

    • object_count optional integer (int64)

    • total_bytes optional integer (int64)

    • tree_idrequired string

    • tree_name optional string

    • unreadable optional string

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

Operation ID get_backup_status

Responses

200

BackupStatusDto

  • backup_location_descriptionrequired string

  • configuredrequired boolean

  • enabledrequired boolean

  • last_failure_at_ms optional integer (int64)

  • last_failure_class optional string

  • last_success_at_ms optional integer (int64)

  • next_run_at_ms optional integer (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.

Operation ID post_restore

Parameters
  • idempotency-keyheader string (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_idrequired string

  • backup_rootrequired string

  • tree_idrequired string

Responses

200

RestoredTreeDto

  • backup_idrequired string

  • bytes_verifiedrequired integer (int64)

  • event_countrequired integer (int64)

  • objects_verifiedrequired integer (int64)

  • source_tree_idrequired string

  • tree_idrequired string

  • tree_namerequired string

403

404

422

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.

Operation ID post_blob

Parameters
  • idempotency-keyheader string (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

Operation ID get_blob

Parameters
  • addressrequiredpath string

    sha256:<hex> content address

Responses

200 — application/octet-stream blob bytes

404

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.

Operation ID post_blob

Parameters
  • idempotency-keyheader string (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

Operation ID get_blob

Parameters
  • addressrequiredpath string

    sha256:<hex> content address

Responses

200 — application/octet-stream blob bytes

404

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

Operation ID get_capabilities

Responses

200

CapabilitiesDto

  • api_versionrequired string

  • app_versionrequired string

  • ingestrequired array of string

  • platformrequired string

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

Operation ID get_citation_templates

Parameters
  • categoryquery optional string

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

Operation ID post_citation

Parameters
  • idempotency-keyheader string (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

Operation ID post_citation_render

Parameters
  • idempotency-keyheader string (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

Operation ID put_citation_elements

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID put_citation_source_type

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID get_citation_templates

Parameters
  • categoryquery optional string

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

Operation ID post_citation

Parameters
  • idempotency-keyheader string (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

Operation ID post_citation_render

Parameters
  • idempotency-keyheader string (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

Operation ID put_citation_elements

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID put_citation_source_type

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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.

Operation ID list_conflicts

Parameters
  • personaquery optional string (uuid)

    Only conflicts recorded against this persona.

  • personquery optional string (uuid)

    Only conflicts about this person's identity, plus every conflict on a persona this person concludes over.

  • limitquery optional integer (int32)

  • cursorquery optional string

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.

Operation ID post_conflict_resolution

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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.

Operation ID list_conflicts

Parameters
  • personaquery optional string (uuid)

    Only conflicts recorded against this persona.

  • personquery optional string (uuid)

    Only conflicts about this person's identity, plus every conflict on a persona this person concludes over.

  • limitquery optional integer (int32)

  • cursorquery optional string

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.

Operation ID post_conflict_resolution

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID get_diagnostics

Responses

200

DiagnosticsDto

  • log_location_description optional string

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

Operation ID get_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.

Operation ID post_feedback

Parameters
  • idempotency-keyheader string (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

  • email optional string

  • messagerequired string

  • name optional string

Responses

202 — delivered to the feedback service

FeedbackAcceptedDto

  • app_versionrequired string

  • platformrequired string

403

422

429

502

503

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

Operation ID post_event

Parameters
  • idempotency-keyheader string (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.

Operation ID sse_stream

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

Operation ID get_event

Parameters
  • idrequiredpath string (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

Operation ID post_event_correction

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID post_event_participant

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID post_event

Parameters
  • idempotency-keyheader string (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.

Operation ID sse_stream

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

Operation ID get_event

Parameters
  • idrequiredpath string (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

Operation ID post_event_correction

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID post_event_participant

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID post_gedcom_export

Parameters
  • idempotency-keyheader string (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

Operation ID get_gedcom_loss_report

Parameters
  • report_idquery optional string (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

Operation ID post_gedcom_validate

Parameters
  • version_hintquery optional string

  • idempotency-keyheader string (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

Operation ID get_imports

Responses

200

Example
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

Operation ID post_import_gedcom

Parameters
  • filenamequery optional string

  • allow_duplicatequery boolean

    Default false. Uploading bytes identical to a previous import refuses synchronously with 409 duplicate-import, before any job is spawned. Set this to import the same file a second time on purpose.

  • idempotency-keyheader string (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

Operation ID post_import_undo

Parameters
  • import_keyrequiredpath string

  • idempotency-keyheader string (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

Operation ID post_gedcom_export

Parameters
  • idempotency-keyheader string (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

Operation ID get_gedcom_loss_report

Parameters
  • report_idquery optional string (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

Operation ID post_gedcom_validate

Parameters
  • version_hintquery optional string

  • idempotency-keyheader string (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

Operation ID get_imports

Responses

200

Example
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

Operation ID post_import_gedcom

Parameters
  • filenamequery optional string

  • allow_duplicatequery boolean

    Default false. Uploading bytes identical to a previous import refuses synchronously with 409 duplicate-import, before any job is spawned. Set this to import the same file a second time on purpose.

  • idempotency-keyheader string (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

Operation ID post_import_undo

Parameters
  • import_keyrequiredpath string

  • idempotency-keyheader string (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

Operation ID connect_claude_desktop

Parameters
  • idempotency-keyheader string (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

ConnectClaudeDesktopResultDto

  • actionrequired string

  • backup_path_descriptionrequired string

  • restart_requiredrequired boolean

403

422

500

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

Operation ID preview_connect_claude_desktop

Parameters
  • idempotency-keyheader string (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

HarnessConnectPreviewDto

  • actionrequired string

  • display_namerequired string

  • existing_keys_preservedrequired array of string

  • harness_idrequired string

  • server_entry_already_existedrequired boolean

  • servers_keyrequired string

  • summaryrequired string

403

422

500

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

Operation ID list_harnesses

Responses

200

HarnessListResponseDto

  • harnessesrequired

    array of

    HarnessListItemDto

    • display_namerequired string

    • idrequired string

    • one_clickrequired boolean

    • vendorrequired string

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

Operation ID list_jobs

Parameters
  • limitquery optional integer (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 optional string

    The next_cursor from 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

Operation ID get_job

Parameters
  • idrequiredpath string (uuid)

Responses
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

Operation ID cancel_job

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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 — cancel requested

404

409

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

Operation ID list_jobs

Parameters
  • limitquery optional integer (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 optional string

    The next_cursor from 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

Operation ID get_job

Parameters
  • idrequiredpath string (uuid)

Responses
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

Operation ID cancel_job

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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 — cancel requested

404

409

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.

Operation ID get_labels

Parameters
  • idsrequiredquery string

    Comma-separated entity ids.

Responses

200

400

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.

Operation ID get_labels

Parameters
  • idsrequiredquery string

    Comma-separated entity ids.

Responses

200

400

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.

Operation ID get_unresolved_media

Responses

200

Example
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.

Operation ID post_media_resolve

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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.

Operation ID get_unresolved_media

Responses

200

Example
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.

Operation ID post_media_resolve

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID get_notes

Parameters
  • targetrequiredquery string

Responses

200

array of NoteDto

400

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

Operation ID post_note

Parameters
  • idempotency-keyheader string (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/notes"

GET /v1/trees/{tree_id}/notes Preview

List notes

Operation ID get_notes

Parameters
  • targetrequiredquery string

Responses

200

array of NoteDto

400

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

Operation ID post_note

Parameters
  • idempotency-keyheader string (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}/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.

Operation ID get_pending

Parameters
  • sourcequery optional string (uuid)

    Keep only pending items whose source equals this source id.

  • proposerquery optional string

    Keep only pending items whose proposer equals this string — the model identifier the creating agent reported for itself.

  • sortquery optional string

    How to order the results. "created" is the only value accepted today.

  • orderquery optional string

    asc (default, oldest first) or desc (newest first). A cursor is only valid against the order it was minted under.

  • limitquery optional integer (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 optional string

    The next_cursor from 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 optional string

    Return the (already filtered and sorted) result set bucketed by source or by proposer instead 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

Operation ID bulk_confirm_pending

Parameters
  • idempotency-keyheader string (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

Operation ID defer_pending

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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/pending/{id}/defer"

POST /v1/pending/{id}/undefer Preview

Undefer a previously-deferred pending assertion

Operation ID undefer_pending

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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/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.

Operation ID get_pending

Parameters
  • sourcequery optional string (uuid)

    Keep only pending items whose source equals this source id.

  • proposerquery optional string

    Keep only pending items whose proposer equals this string — the model identifier the creating agent reported for itself.

  • sortquery optional string

    How to order the results. "created" is the only value accepted today.

  • orderquery optional string

    asc (default, oldest first) or desc (newest first). A cursor is only valid against the order it was minted under.

  • limitquery optional integer (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 optional string

    The next_cursor from 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 optional string

    Return the (already filtered and sorted) result set bucketed by source or by proposer instead 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

Operation ID bulk_confirm_pending

Parameters
  • idempotency-keyheader string (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

Operation ID defer_pending

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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}/pending/{id}/defer"

POST /v1/trees/{tree_id}/pending/{id}/undefer Preview

Undefer a previously-deferred pending assertion

Operation ID undefer_pending

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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}/pending/{id}/undefer"

POST /v1/personas Preview

Create a persona

Operation ID post_persona

Parameters
  • idempotency-keyheader string (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

Operation ID get_persona

Parameters
  • idrequiredpath string (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

Operation ID put_name_pieces

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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/personas/{id}/name-pieces"

POST /v1/trees/{tree_id}/personas Preview

Create a persona

Operation ID post_persona

Parameters
  • idempotency-keyheader string (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

Operation ID get_persona

Parameters
  • idrequiredpath string (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

Operation ID put_name_pieces

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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}/personas/{id}/name-pieces"

GET /v1/fan/query Preview

Query the fan-network relationship view by parameters

Operation ID get_fan_network_query

Parameters
  • persona_idquery optional string (uuid)

  • person_idquery optional string (uuid)

  • window_startquery optional string

  • window_endquery optional string

  • edge_typesquery optional string

    Comma-separated shared_event / association / place_co_occurrence (default: all three).

  • cursorquery optional string

  • limitquery optional integer (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.

Operation ID list_persons

Parameters
  • qquery optional string

    Free-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/order given alongside q is accepted but ignored rather than rejected. Absent ⇒ no name filter.

  • sortquery optional string

    How 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 optional string

    asc (default, oldest first) or desc (newest first). A cursor is only valid against the order it was minted under.

  • limitquery optional integer (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 optional string

    The next_cursor from 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

Operation ID post_person

Parameters
  • idempotency-keyheader string (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

Operation ID get_duplicate_candidates

Parameters
  • givenquery optional string

    Given name as typed so far (whitespace-separated pieces).

  • surnamequery optional string

    Surname as typed so far.

  • birthquery optional string

    Birth 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 optional string

    Death date, same syntax and same strictness as birth.

  • limitquery optional integer (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

Operation ID post_person_merge

Parameters
  • idempotency-keyheader string (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

Operation ID get_person

Parameters
  • idrequiredpath string (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)

Operation ID get_person_card

Parameters
  • idrequiredpath string (uuid)

  • expandquery optional string

    Comma-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

Operation ID get_fan_network

Parameters
  • idrequiredpath string (uuid)

  • window_startquery optional string

  • window_endquery optional string

  • edge_typesquery optional string

    Comma-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

Operation ID put_person_living_status

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID get_pedigree

Parameters
  • idrequiredpath string (uuid)

  • generationsquery optional integer (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

Operation ID post_person_retract

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID post_person_split

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID get_fan_network_query

Parameters
  • persona_idquery optional string (uuid)

  • person_idquery optional string (uuid)

  • window_startquery optional string

  • window_endquery optional string

  • edge_typesquery optional string

    Comma-separated shared_event / association / place_co_occurrence (default: all three).

  • cursorquery optional string

  • limitquery optional integer (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.

Operation ID list_persons

Parameters
  • qquery optional string

    Free-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/order given alongside q is accepted but ignored rather than rejected. Absent ⇒ no name filter.

  • sortquery optional string

    How 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 optional string

    asc (default, oldest first) or desc (newest first). A cursor is only valid against the order it was minted under.

  • limitquery optional integer (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 optional string

    The next_cursor from 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

Operation ID post_person

Parameters
  • idempotency-keyheader string (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

Operation ID get_duplicate_candidates

Parameters
  • givenquery optional string

    Given name as typed so far (whitespace-separated pieces).

  • surnamequery optional string

    Surname as typed so far.

  • birthquery optional string

    Birth 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 optional string

    Death date, same syntax and same strictness as birth.

  • limitquery optional integer (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

Operation ID post_person_merge

Parameters
  • idempotency-keyheader string (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

Operation ID get_person

Parameters
  • idrequiredpath string (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)

Operation ID get_person_card

Parameters
  • idrequiredpath string (uuid)

  • expandquery optional string

    Comma-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

Operation ID get_fan_network

Parameters
  • idrequiredpath string (uuid)

  • window_startquery optional string

  • window_endquery optional string

  • edge_typesquery optional string

    Comma-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

Operation ID put_person_living_status

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID get_pedigree

Parameters
  • idrequiredpath string (uuid)

  • generationsquery optional integer (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

Operation ID post_person_retract

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID post_person_split

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID list_proof_arguments_route

Parameters
  • questionquery optional string (uuid)

  • cursorquery optional string

  • limitquery optional integer (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

Operation ID post_proof_argument

Parameters
  • idempotency-keyheader string (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

Operation ID get_proof_argument_by_id

Parameters
  • idrequiredpath string (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

Operation ID get_proof_argument_export

Parameters
  • idrequiredpath string (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

Operation ID list_proof_arguments_route

Parameters
  • questionquery optional string (uuid)

  • cursorquery optional string

  • limitquery optional integer (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

Operation ID post_proof_argument

Parameters
  • idempotency-keyheader string (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

Operation ID get_proof_argument_by_id

Parameters
  • idrequiredpath string (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

Operation ID get_proof_argument_export

Parameters
  • idrequiredpath string (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

Operation ID list_proposals

Parameters
  • limitquery optional integer (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 optional string

    The next_cursor from 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

Operation ID propose

Parameters
  • idempotency-keyheader string (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

Operation ID approve_proposal

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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)
Responses

200

403

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

Operation ID deny_proposal

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

403

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

Operation ID list_proposals

Parameters
  • limitquery optional integer (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 optional string

    The next_cursor from 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

Operation ID propose

Parameters
  • idempotency-keyheader string (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

Operation ID approve_proposal

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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)
Responses

200

403

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

Operation ID deny_proposal

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

403

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

Operation ID post_redaction

Parameters
  • idempotency-keyheader string (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

Operation ID post_redaction

Parameters
  • idempotency-keyheader string (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

Operation ID post_relationship

Parameters
  • idempotency-keyheader string (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

Operation ID post_relationship_reparent

Parameters
  • idempotency-keyheader string (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

Operation ID post_relationship_unlink

Parameters
  • idempotency-keyheader string (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

Operation ID post_relationship

Parameters
  • idempotency-keyheader string (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

Operation ID post_relationship_reparent

Parameters
  • idempotency-keyheader string (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

Operation ID post_relationship_unlink

Parameters
  • idempotency-keyheader string (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

Operation ID get_project_state

Parameters
  • sincequery optional string

    The cursor value 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

Operation ID get_research_log

Parameters
  • questionrequiredquery string (uuid)

Responses

200

array of string
Example
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

Operation ID add_log_entry

Parameters
  • idempotency-keyheader string (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

Operation ID post_research_log_capture

Parameters
  • idempotency-keyheader string (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

Operation ID get_research_log_entries

Parameters
  • questionquery optional string (uuid)

  • sessionquery optional string (uuid)

  • personaquery optional string (uuid)

  • sourcequery optional string (uuid)

  • cursorquery optional string

  • limitquery optional integer (int32)

  • orderquery optional string

    "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 change order mid-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

Operation ID post_log_negative_record

Parameters
  • idempotency-keyheader string (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

Operation ID get_research_log_entry

Parameters
  • idrequiredpath string (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

Operation ID post_log_detail_append

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID post_log_entry_retract

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID put_log_entry_text

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID delete_plan_item

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID put_plan_item_description

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID put_plan_item_done

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID post_plan_item_reorder

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID list_research_questions_route

Parameters
  • statusquery optional string

    "open" / "closed".

  • subject_kindquery optional string

  • subject_idquery optional string (uuid)

  • cursorquery optional string

  • limitquery optional integer (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

Operation ID open_research_question

Parameters
  • idempotency-keyheader string (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

Operation ID get_research_question

Parameters
  • idrequiredpath string (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

Operation ID close_research_question

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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)
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}/close"

GET /v1/research/questions/{id}/coverage Preview

Get a research question's coverage status

Operation ID get_research_question_coverage

Parameters
  • idrequiredpath string (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

Operation ID confirm_coverage

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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}/coverage-confirm"

GET /v1/research/questions/{id}/plan Preview

Get a research question's plan

Operation ID get_research_plan

Parameters
  • idrequiredpath string (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

Operation ID post_plan_item

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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)

Operation ID post_research_question_reopen

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID put_question_subjects

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID put_research_question_text

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID start_session

Parameters
  • idempotency-keyheader string (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

404

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

Operation ID end_session

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID get_settled

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

Operation ID get_project_state

Parameters
  • sincequery optional string

    The cursor value 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

Operation ID get_research_log

Parameters
  • questionrequiredquery string (uuid)

Responses

200

array of string
Example
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

Operation ID add_log_entry

Parameters
  • idempotency-keyheader string (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

Operation ID post_research_log_capture

Parameters
  • idempotency-keyheader string (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

Operation ID get_research_log_entries

Parameters
  • questionquery optional string (uuid)

  • sessionquery optional string (uuid)

  • personaquery optional string (uuid)

  • sourcequery optional string (uuid)

  • cursorquery optional string

  • limitquery optional integer (int32)

  • orderquery optional string

    "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 change order mid-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

Operation ID post_log_negative_record

Parameters
  • idempotency-keyheader string (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

Operation ID get_research_log_entry

Parameters
  • idrequiredpath string (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

Operation ID post_log_detail_append

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID post_log_entry_retract

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID put_log_entry_text

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID delete_plan_item

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID put_plan_item_description

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID put_plan_item_done

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID post_plan_item_reorder

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID list_research_questions_route

Parameters
  • statusquery optional string

    "open" / "closed".

  • subject_kindquery optional string

  • subject_idquery optional string (uuid)

  • cursorquery optional string

  • limitquery optional integer (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

Operation ID open_research_question

Parameters
  • idempotency-keyheader string (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

Operation ID get_research_question

Parameters
  • idrequiredpath string (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

Operation ID close_research_question

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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)
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}/close"

GET /v1/trees/{tree_id}/research/questions/{id}/coverage Preview

Get a research question's coverage status

Operation ID get_research_question_coverage

Parameters
  • idrequiredpath string (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

Operation ID confirm_coverage

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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}/coverage-confirm"

GET /v1/trees/{tree_id}/research/questions/{id}/plan Preview

Get a research question's plan

Operation ID get_research_plan

Parameters
  • idrequiredpath string (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

Operation ID post_plan_item

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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)

Operation ID post_research_question_reopen

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID put_question_subjects

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID put_research_question_text

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID start_session

Parameters
  • idempotency-keyheader string (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

404

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

Operation ID end_session

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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

Operation ID get_settled

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

Operation ID get_assignment

Parameters
  • idrequiredpath string (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

Operation ID get_session_current

Responses

200

Example
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

Operation ID get_session

Parameters
  • idrequiredpath string (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

Operation ID get_assignment

Parameters
  • idrequiredpath string (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

Operation ID get_session_current

Responses

200

Example
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

Operation ID get_session

Parameters
  • idrequiredpath string (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.

Operation ID list_sources

Parameters
  • qquery optional string

    Case-insensitive substring match on the source title. Applied before pagination, so total counts 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 search GET /v1/persons?q= runs. Absent or blank ⇒ unfiltered.

  • limitquery optional integer (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 optional string

    The next_cursor from 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

Operation ID post_source

Parameters
  • idempotency-keyheader string (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

Operation ID post_source_from_template

Parameters
  • idempotency-keyheader string (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

Operation ID get_source

Parameters
  • idrequiredpath string (uuid)

Responses
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

Operation ID attach_source_blob

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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/{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.

Operation ID list_source_cited_by

Parameters
  • idrequiredpath string (uuid)

  • limitquery optional integer (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 optional string

    The next_cursor from 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.

Operation ID list_sources

Parameters
  • qquery optional string

    Case-insensitive substring match on the source title. Applied before pagination, so total counts 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 search GET /v1/persons?q= runs. Absent or blank ⇒ unfiltered.

  • limitquery optional integer (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 optional string

    The next_cursor from 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

Operation ID post_source

Parameters
  • idempotency-keyheader string (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

Operation ID post_source_from_template

Parameters
  • idempotency-keyheader string (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

Operation ID get_source

Parameters
  • idrequiredpath string (uuid)

Responses
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

Operation ID attach_source_blob

Parameters
  • idrequiredpath string (uuid)

  • idempotency-keyheader string (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/{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.

Operation ID list_source_cited_by

Parameters
  • idrequiredpath string (uuid)

  • limitquery optional integer (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 optional string

    The next_cursor from 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

Operation ID get_telemetry_config

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

Operation ID put_telemetry_config

Parameters
  • idempotency-keyheader string (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_acknowledged optional boolean

  • export_enabled optional boolean

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

Operation ID post_telemetry_event

Parameters
  • idempotency-keyheader string (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

  • eventrequired any

  • seqrequired integer (int32)

  • session_idrequired string (uuid)

Responses

200

TelemetryEventQueuedDto

  • queuedrequired boolean

400

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

Operation ID delete_telemetry_queue

Parameters
  • idempotency-keyheader string (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

  • purgedrequired boolean

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

Operation ID get_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

Operation ID get_tree_stats

Parameters
  • top_surnamesquery optional integer (int32)

    Surname-frequency list cap (default 10, max 50).

Responses
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

Operation ID list_trees

Parameters
  • include_archivedquery optional boolean

Responses

200

array of TreeDto
Example
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

Operation ID create_tree

Parameters
  • idempotency-keyheader string (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

  • namerequired string

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"

GET /v1/trees/active Preview

Get the currently active tree

Operation ID get_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

Operation ID put_active_tree

Parameters
  • idempotency-keyheader string (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_idrequired string

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.

Operation ID claim_tree

Parameters
  • idempotency-keyheader string (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

  • namerequired string

  • provisional_tree_idrequired string

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/claim"

GET /v1/trees/{tree_id} Preview

Get a tree by id

Operation ID get_tree

Parameters
  • tree_idrequiredpath string

Responses
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

Operation ID patch_tree

Parameters
  • tree_idrequiredpath string

  • idempotency-keyheader string (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

  • archived optional boolean

  • name optional string

Responses
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.

Operation ID post_backup_tree

Parameters
  • tree_idrequiredpath string

  • idempotency-keyheader string (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.

Operation ID post_delete_tree

Parameters
  • tree_idrequiredpath string

  • idempotency-keyheader string (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)

Operation ID get_home_person

Parameters
  • tree_idrequiredpath string

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

Operation ID put_home_person

Parameters
  • tree_idrequiredpath string

  • idempotency-keyheader string (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

Operation ID get_root_suggestions

Parameters
  • tree_idrequiredpath string

Responses

200

RootSuggestionsDto

  • person_countrequired integer (int64)

  • suggestionsrequired

    array of

    RootSuggestionDto

    • ancestorsrequired integer (int32)

    • birth_date optional object

    • death_date optional object

    • generationsrequired integer (int32)

    • namerequired string

    • personrequired string (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

Operation ID get_tree_stats

Parameters
  • top_surnamesquery optional integer (int32)

    Surname-frequency list cap (default 10, max 50).

Responses
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

Operation ID post_undo

Parameters
  • idempotency-keyheader string (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

Operation ID get_undo_status

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

Operation ID post_undo

Parameters
  • idempotency-keyheader string (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

Operation ID get_undo_status

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.

Operation ID post_shutdown

Parameters
  • idempotency-keyheader string (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

204 — graceful shutdown initiated; discovery files are removed and the process exits

403

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

Operation ID post_update_check

Parameters
  • idempotency-keyheader string (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

Operation ID post_update_restart

Parameters
  • idempotency-keyheader string (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 — helper spawned; the app is shutting down to swap

409

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

Operation ID get_update_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

Operation ID put_update_settings

Parameters
  • idempotency-keyheader string (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

Operation ID get_update_status

Responses

200

UpdateStatusDto

  • available_version optional string

  • channelrequired string

  • current_versionrequired string

  • error optional string

  • error_kind optional string

  • last_check_at optional integer (int64)

  • notice optional string

  • staged_version optional string

  • staterequired string

Example
curl -sS -X GET \
  -H "Authorization: Bearer $HEARTWOOD_TOKEN" \
  "http://127.0.0.1:$HEARTWOOD_PORT/v1/update/status"
Shared schemas139

AcceptedJobDto

  • job_idrequired string (uuid)

ActiveTreeDto

  • tree_idrequired string

AddLogEntryRequest

  • search_contextrequired string

  • sessionrequired string (uuid)

AddNoteRequest

  • anchors

    array of

    NoteAnchorDto (tagged union)

    kind = assertion

    • idrequired string (uuid)

    • kindrequired string [enum: assertion]

    kind = citation

    • idrequired string (uuid)

    • kindrequired string [enum: citation]

    kind = life_event

    • idrequired string (uuid)

    • kindrequired string [enum: life_event]

    kind = person

    • idrequired string (uuid)

    • kindrequired string [enum: person]

    kind = persona

    • idrequired string (uuid)

    • kindrequired string [enum: persona]

    kind = source

    • idrequired string (uuid)

    • kindrequired string [enum: source]

  • citations array of string (uuid)

  • textrequired string

AddParticipantRequest

  • attached

    array of

    (object, no properties)

  • evidence_class optional object

  • personarequired string (uuid)

  • research_search_contextrequired string

  • research_sessionrequired string (uuid)

  • rolerequired

    (object, no properties)

  • sourcerequired string (uuid)

ApproveRequest

  • summary_shown optional string

AssertionDto

  • claimrequired string

  • created_at_msrequired integer (int64)

  • disposition optional string

  • event_context optional EventContextDto

  • evidencerequired array of EvidenceView

  • fabricatedrequired boolean

  • fact_kind optional string

  • idrequired string (uuid)

  • kindrequired string

  • name optional string

  • personarequired string (uuid)

  • proposer optional string

  • requested_byrequired string

  • sourcerequired string (uuid)

  • statusrequired string

AssignmentDto

  • contentrequired

    AssignmentContentDto (tagged union)

    kind = raw

    • kindrequired string [enum: raw]

    • textrequired string

    kind = structured

    • argumentsrequired map: string → string

    • kindrequired string [enum: structured]

    • prompt_namerequired string

  • idrequired string (uuid)

  • recorded_at_msrequired integer (int64)

AssociationIdDto

  • assertion_idrequired string (uuid)

AttachEvidenceRequest

  • evidencerequired

    (object, no properties)

AttachSourceBlobRequest

  • blobrequired string

BackupConfigDto

  • backup_root_path optional string

  • cadence_hoursrequired integer (int32)

  • enabledrequired boolean

  • retentionrequired BackupRetentionDto

BackupRetentionDto

  • dailyrequired integer (int32)

  • monthlyrequired integer (int32)

  • weeklyrequired integer (int32)

BlobRefDto

  • blobrequired string

BulkConfirmRequest

  • assertion_idsrequired array of string (uuid)

  • batch_note optional string

BulkConfirmResponseDto

  • batch_idrequired string (uuid)

  • confirmedrequired array of string (uuid)

  • duration_msrequired integer (int64)

  • failedrequired

    array of

    BulkConfirmFailureDto

    • idrequired string (uuid)

    • reasonrequired string

CaptureRequest

  • claimrequired string

  • fact_kind any

  • personarequired string (uuid)

  • research_search_contextrequired string

  • research_sessionrequired string (uuid)

  • sourcerequired string (uuid)

ChecklistViewDto

  • analysis_correlationrequired boolean

  • complete_citationsrequired boolean

  • conflict_resolutionrequired boolean

  • exhaustive_searchrequired

    ExhaustiveSearchStatusDto (tagged union)

    status = claimable

    • statusrequired string [enum: claimable]

    status = in_progress

    • coveredrequired integer (int32)

    • statusrequired string [enum: in_progress]

    • totalrequired integer (int32)

    status = not_started

    • statusrequired string [enum: not_started]

  • written_conclusionrequired boolean

CitationRenderRequest

  • citation_id optional string (uuid)

  • elements map: string → string

  • form optional string

  • template_id optional string

CitationRenderResultDto

CitationTemplatesListDto

  • registry_versionrequired integer (int32)

  • templatesrequired

    array of

    CitationTemplateDto

    • categoryrequired string

    • fieldsrequired

      array of

      CitationTemplateFieldDto

      • elementrequired string

      • idrequired string

      • labelrequired string

      • requiredrequired boolean

    • idrequired string

    • labelrequired string

ClaimTranscriptionRequest

  • claimrequired string

  • of_blobrequired string

  • personarequired string (uuid)

  • region

    optional

    RegionDto

    • heightrequired number (double)

    • widthrequired number (double)

    • xrequired number (double)

    • yrequired number (double)

  • research_search_contextrequired string

  • research_sessionrequired string (uuid)

  • sourcerequired string (uuid)

CloseQuestionRequest

  • disposition optional string

  • reason optional string

ConflictClaimDto

  • assertionrequired string (uuid)

  • claimrequired string

  • event

    optional

    ConflictClaimEventDto

    • date optional object

    • date_phrase optional string

    • event_idrequired string (uuid)

    • kindrequired

      (object, no properties)

    • kind_phrase optional string

    • place optional object

    • rolerequired

      (object, no properties)

  • fabricatedrequired boolean

  • fact_kind optional string

  • has_evidencerequired boolean

  • is_confirmablerequired boolean

  • kindrequired string

  • personarequired string (uuid)

  • sourcerequired string (uuid)

  • source_title optional string

  • statusrequired string

ConflictDto

ConflictScopeDto

layer = identity

  • layerrequired string [enum: identity]

  • personrequired string (uuid)

layer = persona

  • layerrequired string [enum: persona]

  • personarequired string (uuid)

CorrectEventRequest

  • evidence

    array of

    (object, no properties)

  • fieldrequired string

  • kind_phrase optional string

  • source_idrequired string (uuid)

  • valuerequired

    (object, no properties)

CorrectionResultDto

  • appliedrequired boolean

  • proposal_id optional string (uuid)

CreateCitationRequest

  • elementsrequired

    array of

    (object, no properties)

CreateCitationResultDto

  • idrequired string (uuid)

CreatePersonaRequest

  • labelrequired string

  • sourcerequired string (uuid)

CreatePersonRequest

  • certaintyrequired

    (object, no properties)

  • personasrequired array of string (uuid)

  • proof_argument optional string (uuid)

CreatePersonResultDto

  • appliedrequired boolean

  • id optional string (uuid)

  • proposal_id optional string (uuid)

CreateSourceRequest

  • titlerequired string

DenyRequest

  • reasonrequired string

DuplicateCandidateDto

  • birth_year optional integer (int32)

  • death_year optional integer (int32)

  • idrequired string (uuid)

  • likelihoodrequired string

  • namerequired string

  • score_permillerequired integer (int32)

EntityLabelDto

  • idrequired string (uuid)

  • kindrequired string

  • labelrequired string

EventContextDto

  • date optional object

  • event_idrequired string (uuid)

  • kindrequired

    (object, no properties)

  • kind_phrase optional string

  • place optional object

  • sibling_participationsrequired

    array of

    SiblingParticipationDto

    • persona_idrequired string (uuid)

    • persona_label_idrequired string

    • rolerequired

      (object, no properties)

    • statusrequired string

  • source_idrequired string (uuid)

EvidenceView

kind = external_record

  • kindrequired string [enum: external_record]

  • recordrequired

    ExternalRecordIdView (tagged union)

    kind = ancestry_record

    • dbidrequired string

    • kindrequired string [enum: ancestry_record]

    • recordrequired string

    kind = doi

    • doirequired string

    • kindrequired string [enum: doi]

    kind = family_search_ark

    • arkrequired string

    • kindrequired string [enum: family_search_ark]

    kind = permalink

    • kindrequired string [enum: permalink]

    • urlrequired string

kind = offline_record

  • citationrequired string

  • kindrequired string [enum: offline_record]

kind = source_blob

  • content_addressrequired string

  • kindrequired string [enum: source_blob]

FanNetworkDto

  • neighborsrequired

    array of

    FanNeighborDto

    • edgesrequired

      array of

      FanEdgeDto

      • assertion optional string (uuid)

      • event optional string (uuid)

      • own_event optional string (uuid)

      • own_role optional string

      • place_id optional string

      • relation optional object

      • their_event optional string (uuid)

      • their_role optional string

      • typerequired string

    • person optional string (uuid)

    • personarequired string (uuid)

GedcomExportRequest

  • destination optional string

  • gedcom_versionrequired string

  • include_living boolean

  • overwrite boolean

GedcomExportResultDto

  • appliedrequired boolean

  • blob optional string

  • file optional string

  • loss_report_id optional string (uuid)

  • messagerequired string

  • proposal_id optional string (uuid)

  • sha256 optional string

HomePersonDto

  • home_person optional string (uuid)

ImportRecordDto

  • assertionsrequired integer (int32)

  • at_msrequired integer (int64)

  • file_name optional string

  • import_keyrequired string

  • in_treerequired

    ImportContentsDto

    • assertionsrequired integer (int32)

    • citationsrequired integer (int32)

    • life_eventsrequired integer (int32)

    • mediarequired integer (int32)

    • notesrequired integer (int32)

    • otherrequired integer (int32)

    • personasrequired integer (int32)

    • sourcesrequired integer (int32)

    • totalrequired integer (int32)

  • personasrequired integer (int32)

  • raw_filerequired string

  • statusrequired string

  • undonerequired boolean

JobDto

  • created_at_msrequired integer (int64)

  • idrequired string (uuid)

  • kindrequired string

  • percent optional integer (int32)

  • reason optional string

  • statusrequired string

  • summary optional string

  • tree_idrequired string

  • updated_at_msrequired integer (int64)

LifeEventDto

  • date optional object

  • date_phrase optional string

  • idrequired string (uuid)

  • kindrequired

    (object, no properties)

  • kind_phrase optional string

  • participationsrequired

    array of

    ParticipantViewDto

    • assertionrequired string (uuid)

    • personarequired string (uuid)

    • persona_labelrequired string

    • rolerequired

      (object, no properties)

    • statusrequired string

  • place optional object

  • sourcerequired string (uuid)

  • source_titlerequired string

LogDetailAppendRequest

  • detailrequired string

LogDetailAppendResponseDto

  • log_entry_idrequired string (uuid)

LogDetailDto

  • attestationrequired string

  • detailrequired string

  • idrequired string (uuid)

  • recorded_atrequired integer (int64)

LogEntryTextSetRequest

  • search_contextrequired string

LogNegativeRecordRequest

  • expectationrequired string

  • inferencerequired string

  • log_entryrequired string (uuid)

  • personarequired string (uuid)

LogNegativeRecordResponseDto

  • negative_evidence_idrequired string (uuid)

LossReportDto

  • created_at_msrequired integer (int64)

  • directionrequired string

  • entriesrequired

    array of

    LossEntryDto

    • categoryrequired string

    • coderequired string

    • countrequired integer (int32)

    • detailrequired string

    • record_refs array of string

    • scoperequired string

    • tag_pathrequired string

  • filerequired

    LossReportFileInfoDto

    • blob optional string

    • completenessrequired string

    • namerequired string

    • sha256required string

  • gedcom_versionrequired string

  • report_idrequired string (uuid)

  • schema_versionrequired integer (int32)

  • totalsrequired

    LossReportTotalsDto

    • entry_countrequired integer (int32)

    • losslessrequired boolean

    • records_dropped optional integer (int32)

    • records_mapped optional integer (int32)

    • records_seen optional integer (int32)

    • structures_emitted optional integer (int32)

    • structures_visited optional integer (int32)

MediaResolveResultDto

  • blobrequired string

  • byte_lenrequired integer (int64)

  • statusrequired string

MergePersonsRequest

  • leftrequired string (uuid)

  • rightrequired string (uuid)

MergePersonsResultDto

  • idrequired string (uuid)

NoteDto

  • citationsrequired array of string (uuid)

  • idrequired string (uuid)

  • requested_byrequired string

  • textrequired string

NoteIdDto

  • note_idrequired string (uuid)

OkResponseDto

  • okrequired boolean

OpenResearchQuestionRequest

  • questionrequired string

Page_AssertionDto

  • itemsrequired

    array of
    • claimrequired string

    • created_at_msrequired integer (int64)

    • disposition optional string

    • event_context optional EventContextDto

    • evidencerequired array of EvidenceView

    • fabricatedrequired boolean

    • fact_kind optional string

    • idrequired string (uuid)

    • kindrequired string

    • name optional string

    • personarequired string (uuid)

    • proposer optional string

    • requested_byrequired string

    • sourcerequired string (uuid)

    • statusrequired string

  • next_cursor optional string

  • totalrequired integer

Page_AuditEntryDto

  • itemsrequired

    array of
    • actorrequired string

    • actor_model optional string

    • actor_reported_harness optional string

    • actor_session optional string (uuid)

    • at_msrequired integer (int64)

    • changes

      array of

      AuditChangeDto

      • fieldrequired string

      • valuerequired string

    • event_typerequired string

    • idrequired string (uuid)

    • kindrequired string [enum: change, session_record]

    • payload any

    • subject

      optional

      AuditSubjectDto

      • idrequired string (uuid)

      • kindrequired string

    • via optional string

  • next_cursor optional string

  • totalrequired integer

Page_ConflictDto

  • itemsrequired

    array of
  • next_cursor optional string

  • totalrequired integer

Page_JobDto

  • itemsrequired

    array of
    • created_at_msrequired integer (int64)

    • idrequired string (uuid)

    • kindrequired string

    • percent optional integer (int32)

    • reason optional string

    • statusrequired string

    • summary optional string

    • tree_idrequired string

    • updated_at_msrequired integer (int64)

  • next_cursor optional string

  • totalrequired integer

Page_PersonDto

  • itemsrequired

    array of
    • birth_date optional object

    • certaintyrequired string

    • death_date optional object

    • idrequired string (uuid)

    • namerequired string

    • updated_at_msrequired integer (int64)

  • next_cursor optional string

  • totalrequired integer

Page_ProposalDto

  • itemsrequired

    array of
    • destination_hint optional string

    • detailsrequired

      ProposalDetailsDto (tagged union)

      kind = conclude_person

      • certaintyrequired string

      • kindrequired string [enum: conclude_person]

      • personasrequired array of string (uuid)

      • proof_argument optional string (uuid)

      kind = correct_event_date

      • eventrequired string (uuid)

      • kindrequired string [enum: correct_event_date]

      • new_daterequired

        (object, no properties)

      • sourcerequired string (uuid)

      kind = correct_event_kind

      • eventrequired string (uuid)

      • kindrequired string [enum: correct_event_kind]

      • kind_phrase optional string

      • new_kindrequired

        (object, no properties)

      • sourcerequired string (uuid)

      kind = correct_event_place

      • eventrequired string (uuid)

      • kindrequired string [enum: correct_event_place]

      • new_placerequired

        (object, no properties)

      • sourcerequired string (uuid)

      kind = export_everything

      • destination_hint optional string

      • kindrequired string [enum: export_everything]

      kind = export_gedcom

      • destination_hint optional string

      • gedcom_versionrequired string

      • include_livingrequired boolean

      • kindrequired string [enum: export_gedcom]

      kind = record_proof_argument

      • certaintyrequired string

      • claims_exhaustive_searchrequired boolean

      • conclusionrequired string

      • contraryrequired array of string (uuid)

      • correlation_reasoningrequired string

      • kindrequired string [enum: record_proof_argument]

      • questionrequired string (uuid)

      • supportingrequired array of string (uuid)

      kind = redact

      • kindrequired string [enum: redact]

      • reasonrequired string

      • targetrequired string (uuid)

      kind = set_citation_elements

      • citationrequired string (uuid)

      • element_countrequired integer (int32)

      • kindrequired string [enum: set_citation_elements]

      kind = undo_gedcom_import

      • import_keyrequired string

      • kindrequired string [enum: undo_gedcom_import]

    • idrequired string (uuid)

    • kindrequired string

    • reason optional string

    • requested_byrequired string

    • statusrequired string

    • target optional string (uuid)

    • target_summary optional string

  • next_cursor optional string

  • totalrequired integer

Page_SourceCitedClaimDto

  • itemsrequired

    array of
    • assertionrequired string (uuid)

    • claimrequired string

    • kindrequired string

    • person optional string (uuid)

    • person_name optional string

    • personarequired string (uuid)

    • persona_labelrequired string

    • statusrequired string

  • next_cursor optional string

  • totalrequired integer

Page_SourceListItemDto

  • itemsrequired

    array of
    • claim_countrequired integer

    • has_citationrequired boolean

    • idrequired string (uuid)

    • titlerequired string

  • next_cursor optional string

  • totalrequired integer

Page_UnsourcedAssertionDto

  • itemsrequired

    array of
    • assertionrequired AssertionDto

    • person optional string (uuid)

    • persona_labelrequired string

  • next_cursor optional string

  • totalrequired integer

ParticipationIdDto

  • participation_idrequired string (uuid)

PedigreeDto

  • anchorrequired string (uuid)

  • generationsrequired integer (int32)

  • slotsrequired

    array of

    PedigreeSlotDto

    • birth_date optional object

    • death_date optional object

    • has_more_ancestorsrequired boolean

    • namerequired string

    • personrequired string (uuid)

    • slotrequired integer (int64)

PendingPageDto

  • groups

    optional array of

    PendingGroupDto

    • countrequired integer (int32)

    • group_key optional string

    • itemsrequired array of AssertionDto

  • itemsrequired array of AssertionDto

  • next_cursor optional string

PersonaDto

  • concluded_person optional string (uuid)

  • idrequired string (uuid)

  • labelrequired string

  • person_birth_date optional object

  • person_death_date optional object

  • person_name optional string

  • sourcerequired string (uuid)

PersonCardDto

  • assertion_countrequired integer (int32)

  • assertions

    optional array of

    PersonCardAssertionDto

    • claimrequired string

    • idrequired string (uuid)

    • kindrequired string

    • personarequired string (uuid)

    • persona_labelrequired string

    • sourcerequired string (uuid)

    • source_titlerequired string

    • staterequired string

  • birth_year optional integer (int32)

  • childrenrequired array of PersonSummaryDto

  • death_year optional integer (int32)

  • events optional array of LifeEventDto

  • idrequired string (uuid)

  • namerequired string

  • parentsrequired array of PersonSummaryDto

  • source_countrequired integer (int32)

  • sources

    optional array of

    PersonCardSourceDto

    • has_citationrequired boolean

    • idrequired string (uuid)

    • titlerequired string

  • spousesrequired array of PersonSummaryDto

PersonDetailDto

  • birth_date optional object

  • certaintyrequired string

  • death_date optional object

  • idrequired string (uuid)

  • namerequired string

  • personasrequired array of string (uuid)

  • updated_at_msrequired integer (int64)

PersonSummaryDto

  • birth_year optional integer (int32)

  • death_year optional integer (int32)

  • idrequired string (uuid)

  • namerequired string

PlanItemAddRequest

  • descriptionrequired string

  • position optional integer (int32)

  • source_id optional string (uuid)

PlanItemAddResponseDto

  • item_idrequired string (uuid)

PlanItemDescriptionSetRequest

  • descriptionrequired string

PlanItemDoneSetRequest

  • donerequired boolean

PlanItemDoneSetResponseDto

  • donerequired boolean

  • itemrequired string (uuid)

PlanItemReorderRequest

  • positionrequired integer (int32)

Problem

  • detailrequired string

  • statusrequired integer (int32)

  • titlerequired string

  • typerequired string

ProofArgumentDto

  • certaintyrequired string

  • claims_exhaustive_searchrequired boolean

  • conclusionrequired string

  • contrary_evidencerequired

    array of

    ContraryTreatmentView

    • assertionrequired string (uuid)

    • treatmentrequired string

  • correlation_reasoningrequired string

  • idrequired string (uuid)

  • questionrequired string (uuid)

  • supportingrequired array of string (uuid)

ProofArgumentExportDto

  • certaintyrequired string

  • claims_exhaustive_searchrequired boolean

  • gps_checklistrequired ChecklistViewDto

  • idrequired string (uuid)

  • provenancerequired

    ExportProvenanceDto

    • at_msrequired integer (int64)

    • creatorrequired string

    • via optional string

  • questionrequired

    ExportQuestionDto

    • idrequired string (uuid)

    • textrequired string

  • schemarequired string

  • sectionsrequired

    array of

    ExportSectionDto

    • bodyrequired string

    • citationsrequired

      array of

      ExportCitationDto

      • assertion_idrequired string (uuid)

      • citation_idrequired string (uuid)

      • rendered_footnoterequired string

    • kindrequired string

ProofArgumentListResponseDto

ProposeRedactRequest

  • reasonrequired string

  • targetrequired string (uuid)

QuestionCoverageResponseDto

QuestionDto

  • idrequired string (uuid)

  • questionrequired string

  • statusrequired string

  • subjectsrequired array of SubjectRefDto

QuestionSubjectsSetRequest

QuestionTextSetRequest

  • textrequired string

RecordAssociationRequest

  • attached

    array of

    (object, no properties)

  • evidence_class optional object

  • otherrequired string (uuid)

  • personarequired string (uuid)

  • relationrequired

    (object, no properties)

  • research_search_contextrequired string

  • research_sessionrequired string (uuid)

  • sourcerequired string (uuid)

RecordedLifeEventDto

  • event_idrequired string (uuid)

  • participation_idsrequired array of string (uuid)

RecordLifeEventRequest

  • date optional object

  • kindrequired

    (object, no properties)

  • kind_phrase optional string

  • participantsrequired

    array of

    ParticipantInputDto

    • attached

      array of

      (object, no properties)

    • evidence_class optional object

    • personarequired string (uuid)

    • rolerequired

      (object, no properties)

  • place optional object

  • research_search_contextrequired string

  • research_sessionrequired string (uuid)

  • sourcerequired string (uuid)

RecordProofArgumentRequest

  • certaintyrequired

    (object, no properties)

  • claims_exhaustive_searchrequired boolean

  • conclusionrequired string

  • contrary_evidencerequired

    (object, no properties)

  • correlation_reasoningrequired string

  • questionrequired string (uuid)

  • supportingrequired array of string (uuid)

RecordProofArgumentResultDto

  • appliedrequired boolean

  • argument optional ProofArgumentDto

  • proposal_id optional string (uuid)

RedactionRequest

  • reasonrequired string

  • summary_shownrequired string

  • targetrequired string (uuid)

RedactionResultDto

  • blobs_purgedrequired integer

  • redactedrequired boolean

RelationshipAttachRequest

  • kindrequired string

  • personrequired string (uuid)

  • relativerequired string (uuid)

  • research_search_contextrequired string

  • research_sessionrequired string (uuid)

  • sourcerequired string (uuid)

RelationshipOutcomeDto

  • assertionsrequired array of string (uuid)

  • createdrequired boolean

  • eventrequired string (uuid)

RelationshipReparentRequest

  • childrequired string (uuid)

  • from_parentrequired string (uuid)

  • research_search_contextrequired string

  • research_sessionrequired string (uuid)

  • sourcerequired string (uuid)

  • to_parentrequired string (uuid)

RelationshipUnlinkRequest

  • kindrequired string

  • personrequired string (uuid)

  • relativerequired string (uuid)

  • research_search_contextrequired string

  • research_sessionrequired string (uuid)

RenderedTextDto

  • htmlrequired string

  • textrequired string

ResearchLogCaptureRequest

  • found_nothing boolean

  • persona optional string (uuid)

  • question optional string (uuid)

  • search_contextrequired string

  • session optional string (uuid)

  • source optional string (uuid)

ResearchLogCaptureResponseDto

  • linkedrequired

    ResearchLogCaptureLinkedDto

    • persona optional string (uuid)

    • plan_item optional string (uuid)

    • source optional string (uuid)

  • log_entry_idrequired string (uuid)

  • session_idrequired string (uuid)

ResearchLogEntryDto

  • attestationrequired string

  • detailsrequired array of LogDetailDto

  • found_nothingrequired boolean

  • idrequired string (uuid)

  • persona optional string (uuid)

  • plan_item optional string (uuid)

  • question optional string (uuid)

  • recorded_atrequired integer (int64)

  • search_contextrequired string

  • sessionrequired string (uuid)

  • source optional string (uuid)

ResearchLogListResponseDto

  • entriesrequired

    array of

    ResearchLogListEntryDto

    • attestationrequired string

    • detailsrequired array of LogDetailDto

    • found_nothingrequired boolean

    • idrequired string (uuid)

    • persona optional string (uuid)

    • plan_item optional string (uuid)

    • question optional string (uuid)

    • recorded_atrequired integer (int64)

    • search_contextrequired string

    • sessionrequired string (uuid)

    • source optional string (uuid)

  • next_cursor optional string

  • totalrequired integer

ResearchPlanGetResponseDto

  • coveragerequired ChecklistViewDto

  • itemsrequired

    array of

    PlanItemDto

    • descriptionrequired string

    • donerequired boolean

    • idrequired string (uuid)

    • log_entry_countrequired integer (int32)

    • positionrequired integer (int32)

    • source_id optional string (uuid)

ResearchQuestionDto

  • idrequired string (uuid)

  • questionrequired string

ResearchQuestionListResponseDto

  • itemsrequired array of QuestionDto

  • next_cursor optional string

ResolveConflictRequest

  • proof_argumentrequired string (uuid)

ResolveMediaRequest

  • blobrequired string

SessionBriefDto

  • conflictsrequired

    ConflictDetectionBriefDto

    • conflicts_recordedrequired integer

    • detection_has_runrequired boolean

    • imports_observedrequired integer

    • open_conflictsrequired integer

    • triggerrequired string

  • cursorrequired string

  • open_questionsrequired

    OpenQuestionsSectionDto

    • itemsrequired

      array of

      OpenQuestionBriefDto

      • gpsrequired ChecklistViewDto

      • idrequired string (uuid)

      • log_entriesrequired integer

      • plan_itemsrequired integer

      • questionrequired string

      • subjectsrequired integer

    • totalrequired integer

  • pendingrequired

    PendingLaneBriefDto

    • deferredrequired integer

    • depthrequired integer

  • retiredrequired

    RetiredSectionDto

    • itemsrequired

      array of

      RetiredLeadBriefDto

      • closed_at_msrequired integer (int64)

      • disposition optional string

      • idrequired string (uuid)

      • questionrequired string

      • reason optional string

    • totalrequired integer

  • rulesrequired array of string

  • settledrequired

    SettledSectionDto

    • confirmed_assertionsrequired

      ConfirmedAssertionsSectionDto

      • itemsrequired

        array of

        ConfirmedAssertionBriefDto

        • claimrequired string

        • idrequired string (uuid)

      • totalrequired integer

    • proof_argumentsrequired

      ProofArgumentsSectionDto

      • itemsrequired

        array of

        ProofArgumentBriefDto

        • certaintyrequired string

        • conclusionrequired string

        • idrequired string (uuid)

        • questionrequired string (uuid)

        • recorded_at_msrequired integer (int64)

      • totalrequired integer

  • since optional string

SessionSummaryDto

  • actor_model optional string

  • actor_reported_harness optional string

  • current_assignment optional string (uuid)

  • event_countrequired integer

  • first_seen_at_msrequired integer (int64)

  • last_seen_at_msrequired integer (int64)

  • sessionrequired string (uuid)

SetCitationElementsRequest

  • elementsrequired map: string → string

SetCitationElementsResultDto

  • appliedrequired boolean

  • proposal_id optional string (uuid)

  • rendered optional CitationRenderResultDto

  • revision optional integer (int32)

SetCitationSourceTypeRequest

  • template_idrequired string

SetCitationSourceTypeResultDto

  • appliedrequired boolean

  • missing_required optional array of string

  • proposal_id optional string (uuid)

  • revision optional integer (int32)

  • template_id optional string

SetLivingStatusRequest

  • statusrequired

    (object, no properties)

SetNamePiecesRequest

  • piecesrequired

    (object, no properties)

  • research_search_contextrequired string

  • research_sessionrequired string (uuid)

SettledKnowledgeDto

  • conclusionsrequired

    array of

    SettledConclusionDto

    • certaintyrequired string

    • conclusionrequired string

    • idrequired string (uuid)

    • questionrequired string (uuid)

    • question_textrequired string

    • recorded_at_msrequired integer (int64)

    • recorded_byrequired string

  • negative_findingsrequired

    array of

    NegativeFindingDto

    • expectationrequired string

    • inferencerequired string

    • log_entryrequired string (uuid)

    • question optional string (uuid)

    • recorded_at_msrequired integer (int64)

    • recorded_byrequired string

    • search_context optional string

  • refutationsrequired

    array of

    RuledOutAssertionDto

    • claimrequired string

    • idrequired string (uuid)

    • ruled_out_at_ms optional integer (int64)

    • ruled_out_by optional string

    • statusrequired string

  • rejected_evidencerequired

    array of

    RejectedEvidenceDto

    • assertionrequired string (uuid)

    • proof_argumentrequired string (uuid)

    • recorded_at_msrequired integer (int64)

    • recorded_byrequired string

    • treatmentrequired string

  • retired_leadsrequired

    array of

    RetiredLeadDto

    • closed_at_msrequired integer (int64)

    • disposition optional string

    • idrequired string (uuid)

    • questionrequired string

    • reason optional string

SourceDto

  • blobsrequired array of string

  • citation

    optional

    SourceCitationDto

    • bibliography optional string

    • elementsrequired

      array of

      CitationElementDto

      • kindrequired string

      • label optional string

      • valuerequired string

    • field_values map: string → string

    • finalized_prose optional string

    • first optional string

    • idrequired string (uuid)

    • missing_required array of string

    • revision optional integer (int32)

    • subsequent optional string

  • claim_countrequired integer

  • derived_from optional string (uuid)

  • idrequired string (uuid)

  • titlerequired string

SourceFromTemplateRequest

  • elementsrequired map: string → string

  • template_idrequired string

  • title optional string

SourceFromTemplateResultDto

  • citation_idrequired string (uuid)

  • createdrequired boolean

  • renderedrequired CitationRenderResultDto

  • source_idrequired string (uuid)

SourcingTallyDto

  • needs_sourcerequired integer

  • sourcedrequired integer

  • totalrequired integer

SplitPersonRequest

  • leftrequired array of string (uuid)

  • rightrequired array of string (uuid)

SplitPersonResultDto

  • leftrequired string (uuid)

  • rightrequired string (uuid)

StartSessionRequest

  • questionrequired string (uuid)

SubjectRefDto

kind = life_event

  • idrequired string (uuid)

  • kindrequired string [enum: life_event]

kind = person

  • idrequired string (uuid)

  • kindrequired string [enum: person]

kind = persona

  • idrequired string (uuid)

  • kindrequired string [enum: persona]

SupersedeAssertionRequest

  • byrequired string (uuid)

TelemetryConfigDto

  • acknowledged_schema_version optional integer (int32)

  • backlog_purged_at optional string

  • disclosure_acknowledgedrequired boolean

  • export_enabledrequired boolean

  • last_export_at optional string

TreeDto

  • archivedrequired boolean

  • created_at_msrequired integer (int64)

  • idrequired string

  • last_modified_at_ms optional integer (int64)

  • location optional string

  • namerequired string

  • person_count optional integer (int32)

  • size_bytes optional integer (int64)

  • store_missingrequired boolean

TreeStatsDto

  • birth_year_max optional integer (int32)

  • birth_year_min optional integer (int32)

  • missing_birth_date_countrequired integer (int32)

  • missing_death_date_countrequired integer (int32)

  • person_countrequired integer (int32)

  • read_onlyrequired boolean

  • read_only_reasonsrequired array of string

  • refused_segmentsrequired integer (int32)

  • source_countrequired integer (int32)

  • top_surnamesrequired

    array of

    SurnameCountDto

    • countrequired integer (int32)

    • surnamerequired string

UndoImportRequest

  • summary_shownrequired string

UndoRequest

  • event optional string (uuid)

UndoResponse

  • compensatingrequired array of string (uuid)

  • undonerequired string (uuid)

  • undone_event_typerequired string

UndoStatusResponse

  • last_edit

    optional

    EditDispositionDto

    • eventrequired string (uuid)

    • event_typerequired string

    • undoablerequired

      UndoableNowDto

      • issue optional string

      • rationale optional string

      • staterequired string

  • target

    optional

    UndoTargetDto

    • at_msrequired integer (int64)

    • eventrequired string (uuid)

    • event_typerequired string

UnresolvedMediaDto

  • file_namerequired string

  • kindrequired string

  • media_idrequired string (uuid)

UpdateSettingsDto

  • check_automaticallyrequired boolean

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).