---
title: "data problems in the kinship relations and affiliations: loops in the Parent/Ancestor graph, suspicious parents, duplicate rows, incompatible relations between the same two people, self relations - the worklist for cleaning the family-tree data (Auth policies: ganjoor:modify)"
method: GET
path: "/api/people/relations/problems"
tags: ["GanjoorRelatedPerson"]
---

# data problems in the kinship relations and affiliations: loops in the Parent/Ancestor graph, suspicious parents, duplicate rows, incompatible relations between the same two people, self relations - the worklist for cleaning the family-tree data (Auth policies: ganjoor:modify)

`GET /api/people/relations/problems`

## Request

- Base URL: `https://api.ganjoor.net` (the document declares no server; this is the origin it was published from)
- URL: `https://api.ganjoor.net/api/people/relations/problems`
- Auth: API key in header `Authorization`

## Response `200`

OK

- GanjoorRelationProblemsViewModel: everything the relation checker found
  - `relationsChecked` integer: number of kinship relations checked
  - `affiliationsChecked` integer: number of affiliations checked
  - `cycles` GanjoorRelationCycleProblem[], nullable: loops in the Parent/Ancestor graph
    - `people` GanjoorRelationProblemPerson[], nullable: people on the loop(s)
      - `id` integer: person id
      - `name` string, nullable: name
    - `edges` GanjoorRelationProblemEdge[], nullable: all Parent/Ancestor relations between those people
      - `relationId` integer: relation or affiliation id
      - `isAffiliation` boolean: true for a non-family affiliation row
      - `person1Id` integer: first person (the parent/ancestor for directional kinship types)
      - `person1Name` string, nullable: first person's name
      - `person2Id` integer: second person (the child/descendant for directional kinship types)
      - `person2Name` string, nullable: second person's name
      - `relationType` 0 | 1 | 2 | 3: the kind of kinship edge a GanjoorPersonRelation represents between two GanjoorRelatedPerson rows. The graph is not a strict tree - siblings can be known without their parents, an ancestor can be known without the exact number of generations in between, etc. - so this is a small, deliberately open set rather than a rigid parent/child-only model.
      - `affiliationType` 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 99: the kind of non-family tie a GanjoorPersonAffiliation represents between two people - e.g. a minister serving a king, an advisor, a patron. Unlike PersonRelationType this has nothing to do with kinship; it's what lets two otherwise unrelated family trees show up as adjacent (e.g. "some Barmakids served the Abbasid court") without merging them into one tree. New values can be appended safely later (stored as int) as more cases come up.
      - `degreeHint` integer, nullable: exact generations for an Ancestor relation, when known
      - `note` string, nullable: free-text note
      - `evidenceCount` integer: number of human-attached evidence couplets
      - `books` GanjoorRelationProblemBook[], nullable: books attesting it
        - `id` integer: category id
        - `title` string, nullable: category title, when it could be found
    - `suggestedRelationId` integer, nullable: the relation that is the best first candidate for removal or correction: an Ancestor one (a looser claim than Parent) with the fewest evidence couplets. Removing it may not break every loop of a large group.
  - `parentProblems` GanjoorRelationParentsProblem[], nullable: suspicious parents
    - `kind` 0 | 1 | 2: what is wrong with a person's recorded parents
    - `child` GanjoorRelationProblemPerson: a person named in a problem
      - `id` integer: person id
      - `name` string, nullable: name
    - `book` GanjoorRelationProblemBook: a book (master category) that attests a relation or affiliation
      - `id` integer: category id
      - `title` string, nullable: category title, when it could be found
    - `parentEdges` GanjoorRelationProblemEdge[], nullable: the Parent relations involved
      - `relationId` integer: relation or affiliation id
      - `isAffiliation` boolean: true for a non-family affiliation row
      - `person1Id` integer: first person (the parent/ancestor for directional kinship types)
      - `person1Name` string, nullable: first person's name
      - `person2Id` integer: second person (the child/descendant for directional kinship types)
      - `person2Name` string, nullable: second person's name
      - `relationType` 0 | 1 | 2 | 3: the kind of kinship edge a GanjoorPersonRelation represents between two GanjoorRelatedPerson rows. The graph is not a strict tree - siblings can be known without their parents, an ancestor can be known without the exact number of generations in between, etc. - so this is a small, deliberately open set rather than a rigid parent/child-only model.
      - `affiliationType` 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 99: the kind of non-family tie a GanjoorPersonAffiliation represents between two people - e.g. a minister serving a king, an advisor, a patron. Unlike PersonRelationType this has nothing to do with kinship; it's what lets two otherwise unrelated family trees show up as adjacent (e.g. "some Barmakids served the Abbasid court") without merging them into one tree. New values can be appended safely later (stored as int) as more cases come up.
      - `degreeHint` integer, nullable: exact generations for an Ancestor relation, when known
      - `note` string, nullable: free-text note
      - `evidenceCount` integer: number of human-attached evidence couplets
      - `books` GanjoorRelationProblemBook[], nullable: books attesting it
        - `id` integer: category id
        - `title` string, nullable: category title, when it could be found
  - `duplicates` GanjoorRelationDuplicateProblem[], nullable: identical rows
    - `edges` GanjoorRelationProblemEdge[], nullable: the identical rows
      - `relationId` integer: relation or affiliation id
      - `isAffiliation` boolean: true for a non-family affiliation row
      - `person1Id` integer: first person (the parent/ancestor for directional kinship types)
      - `person1Name` string, nullable: first person's name
      - `person2Id` integer: second person (the child/descendant for directional kinship types)
      - `person2Name` string, nullable: second person's name
      - `relationType` 0 | 1 | 2 | 3: the kind of kinship edge a GanjoorPersonRelation represents between two GanjoorRelatedPerson rows. The graph is not a strict tree - siblings can be known without their parents, an ancestor can be known without the exact number of generations in between, etc. - so this is a small, deliberately open set rather than a rigid parent/child-only model.
      - `affiliationType` 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 99: the kind of non-family tie a GanjoorPersonAffiliation represents between two people - e.g. a minister serving a king, an advisor, a patron. Unlike PersonRelationType this has nothing to do with kinship; it's what lets two otherwise unrelated family trees show up as adjacent (e.g. "some Barmakids served the Abbasid court") without merging them into one tree. New values can be appended safely later (stored as int) as more cases come up.
      - `degreeHint` integer, nullable: exact generations for an Ancestor relation, when known
      - `note` string, nullable: free-text note
      - `evidenceCount` integer: number of human-attached evidence couplets
      - `books` GanjoorRelationProblemBook[], nullable: books attesting it
        - `id` integer: category id
        - `title` string, nullable: category title, when it could be found
  - `pairConflicts` GanjoorRelationPairConflictProblem[], nullable: incompatible relations between the same two people
    - `kind` 0 | 1 | 2 | 3: kinds of incompatible relations between the same two people
    - `edges` GanjoorRelationProblemEdge[], nullable: the relations involved
      - `relationId` integer: relation or affiliation id
      - `isAffiliation` boolean: true for a non-family affiliation row
      - `person1Id` integer: first person (the parent/ancestor for directional kinship types)
      - `person1Name` string, nullable: first person's name
      - `person2Id` integer: second person (the child/descendant for directional kinship types)
      - `person2Name` string, nullable: second person's name
      - `relationType` 0 | 1 | 2 | 3: the kind of kinship edge a GanjoorPersonRelation represents between two GanjoorRelatedPerson rows. The graph is not a strict tree - siblings can be known without their parents, an ancestor can be known without the exact number of generations in between, etc. - so this is a small, deliberately open set rather than a rigid parent/child-only model.
      - `affiliationType` 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 99: the kind of non-family tie a GanjoorPersonAffiliation represents between two people - e.g. a minister serving a king, an advisor, a patron. Unlike PersonRelationType this has nothing to do with kinship; it's what lets two otherwise unrelated family trees show up as adjacent (e.g. "some Barmakids served the Abbasid court") without merging them into one tree. New values can be appended safely later (stored as int) as more cases come up.
      - `degreeHint` integer, nullable: exact generations for an Ancestor relation, when known
      - `note` string, nullable: free-text note
      - `evidenceCount` integer: number of human-attached evidence couplets
      - `books` GanjoorRelationProblemBook[], nullable: books attesting it
        - `id` integer: category id
        - `title` string, nullable: category title, when it could be found
  - `selfRelations` GanjoorRelationProblemEdge[], nullable: rows relating a person to themselves
    - `relationId` integer: relation or affiliation id
    - `isAffiliation` boolean: true for a non-family affiliation row
    - `person1Id` integer: first person (the parent/ancestor for directional kinship types)
    - `person1Name` string, nullable: first person's name
    - `person2Id` integer: second person (the child/descendant for directional kinship types)
    - `person2Name` string, nullable: second person's name
    - `relationType` 0 | 1 | 2 | 3: the kind of kinship edge a GanjoorPersonRelation represents between two GanjoorRelatedPerson rows. The graph is not a strict tree - siblings can be known without their parents, an ancestor can be known without the exact number of generations in between, etc. - so this is a small, deliberately open set rather than a rigid parent/child-only model.
    - `affiliationType` 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 99: the kind of non-family tie a GanjoorPersonAffiliation represents between two people - e.g. a minister serving a king, an advisor, a patron. Unlike PersonRelationType this has nothing to do with kinship; it's what lets two otherwise unrelated family trees show up as adjacent (e.g. "some Barmakids served the Abbasid court") without merging them into one tree. New values can be appended safely later (stored as int) as more cases come up.
    - `degreeHint` integer, nullable: exact generations for an Ancestor relation, when known
    - `note` string, nullable: free-text note
    - `evidenceCount` integer: number of human-attached evidence couplets
    - `books` GanjoorRelationProblemBook[], nullable: books attesting it
      - `id` integer: category id
      - `title` string, nullable: category title, when it could be found

## Other responses

- `400`: Bad Request
- `401`: Unauthorized
- `403`: Forbidden

## Changes

- **2026-10-13** `afb4560919ee`: 5 warning
  - added the new `15.00` enum value to the `cycles/items/edges/items/affiliationType` response property for the response status `200`
  - added the new `15.00` enum value to the `duplicates/items/edges/items/affiliationType` response property for the response status `200`
  - added the new `15.00` enum value to the `pairConflicts/items/edges/items/affiliationType` response property for the response status `200`
  - added the new `15.00` enum value to the `parentProblems/items/parentEdges/items/affiliationType` response property for the response status `200`
  - …1 more
- **2026-10-12** `7e8c1526f0a9`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/ganjoor/apis/rmuseum-api/changes/api/people/relations/problems/get.md)

---

[API](https://skmtc.dev/ganjoor/apis/rmuseum-api.md) - [All operations](https://skmtc.dev/ganjoor/apis/rmuseum-api/llms.txt) - [OpenAPI document](https://skmtc.dev/ganjoor/apis/rmuseum-api/revisions/143b912b1085?raw)
