API documentation
People, families and merges
Read a person's close family and tree, add or remove relatives, merge and unmerge duplicates, and resolve conflicts.
Last updated October 16, 2026
Beyond creating and editing people, the API covers the work you do on relationships in the app: linking relatives, reading the tree, merging duplicates and undoing a merge, and resolving conflicts.
Read a person's close family
curl https://kleiobase.com/api/v1/workspaces/WORKSPACE_ID/people/PERSON_ID/family \
-H "Authorization: Bearer kb_live_YOUR_KEY"
You get parents, partners and children. Each entry carries the family_id it comes through and, for parents and children, the pedigree of the link (null means biological). A partner entry whose person_id is null is a family the person heads alone.
Read the tree
GET .../people/{person_id}/tree walks the tree from a person and returns nodes (people), unions (families) and edges between them. It is data only, with no layout.
direction:ancestors,descendantsorboth(defaultboth).depth: 1 to 8 generations (default 4).truncatedistruewhen relatives exist beyond the depth.
Add or remove a relative
Link an existing person, or create a new one in the same request with new_person:
curl -X POST https://kleiobase.com/api/v1/workspaces/WORKSPACE_ID/people/PERSON_ID/relatives \
-H "Authorization: Bearer kb_live_YOUR_KEY" \
-H "Idempotency-Key: add-father-1" \
-H "Content-Type: application/json" \
-d '{"type": "parent", "new_person": {"given_name": "Josef", "surname": "Novak", "gender": "M"}}'
type is partner, parent, child, sibling or associate. The same rules apply as in the app, including your plan's person limit (403 forbidden). You get 201 when a person was created and 200 when an existing one was linked. Either way the body has the relative's person_id.
To remove a link, send DELETE to the same URL with {"person_id": "...", "type": "parent"}. The people themselves are not deleted.
To change a couple's relationship status or a family event such as a marriage, use PATCH .../families/{family_id}.
Records a person should have
GET .../people/{person_id}/expected-records lists research targets, such as a census the person should appear in, highest priority first. To dismiss one, send PATCH .../expected-records/{expected_record_id} with {"dismissed": true}.
Merge and unmerge
Merging two people (POST .../people/{person_id}/merge) and accepting a match (POST .../matches/{match_id}/accept) both return a match_id. Keep it: it is how you undo the merge.
curl -X POST https://kleiobase.com/api/v1/workspaces/WORKSPACE_ID/people/SURVIVOR_ID/unmerge \
-H "Authorization: Bearer kb_live_YOUR_KEY" \
-H "Idempotency-Key: unmerge-1" \
-H "Content-Type: application/json" \
-d '{"match_id": "MATCH_ID"}'
The person in the path must be the merge's survivor. The response lists restored_person_ids.
Merge a group of duplicates
POST .../matches/merge-group merges 2 to 20 people into one survivor:
{ "person_ids": ["ID_1", "ID_2", "ID_3"], "survivor_id": "ID_1" }
The response has one match_id per merged person. Unmerging any one of them undoes the whole group. If a later person cannot be merged, the earlier merges stand and that person is listed in failed.
Resolve conflicts
GET .../conflicts lists them. Two kinds can be resolved through the API, as in the app:
- A person with more than one birth family:
POST .../conflicts/resolvewithactionkeep_family(keepfamily_idas the birth family and mark the others adopted) orchange_pedi(setpedigreeon the link tofamily_id). - Spelling variants of a fact, such as an occupation written two ways:
POST .../conflicts/fact-variants/resolvefoldsfolded_valuesintokeep_value, andpin_valueskeeps values apart as genuinely different facts.
Both return the person's conflicts after the change.
Building a product on KleioBase? Contact us.