> ## Documentation Index
> Fetch the complete documentation index at: https://docs.omophub.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Get Concept Ancestors

> Retrieve all ancestor OMOP concepts for a given concept - hierarchical context, classification paths, and parent terms for concept set expansion.

This endpoint returns the complete ancestor hierarchy for a specific concept, including parent concepts, grandparents, and all higher-level classifications up to the root of the vocabulary hierarchy.

## Path Parameters

<ParamField path="concept_id" type="integer" required>
  The unique identifier of the concept to retrieve ancestors for

  <br />

  **Example:** `201826` (Type 2 diabetes mellitus)
</ParamField>

## Query Parameters

<ParamField query="vocabulary_ids" type="string" optional>
  Filter ancestors to specific vocabularies (comma-separated)

  <br />

  **Example:** `SNOMED,ICD10CM`
</ParamField>

<ParamField query="domain_ids" type="string" optional>
  Filter ancestors to specific domains (comma-separated)

  <br />

  **Example:** `Condition,Observation`
</ParamField>

<ParamField query="max_levels" type="integer" optional default="10">
  Maximum number of hierarchy levels to traverse

  <br />

  **Range:** `1-20`
</ParamField>

<Warning>
  **This endpoint always traverses the `Is a` hierarchy.** It reads OMOP's
  precomputed `concept_ancestor` closure, which stores only transitive `Is a`
  ancestry - it has no relationship column to filter on. Every ancestor is
  therefore returned with `relationship_id: "Is a"`.

  A `relationship_types` parameter is accepted for backwards compatibility but has
  **no effect here**: passing `Part of`, or even a nonexistent relationship, returns
  the same `Is a` ancestors. To traverse other relationship types, use
  [`GET /v1/concepts/{concept_id}/relationships`](/api-reference/concepts/get-concept-relationships)
  or [`POST /v1/concepts/relationships/traverse`](/api-reference/concepts/traverse-relationships),
  which query `concept_relationship` directly.
</Warning>

<ParamField query="include_distance" type="boolean" optional default="false">
  Include `hierarchy_level` field for each ancestor (distance from source concept)
</ParamField>

<ParamField query="include_paths" type="boolean" optional default="false">
  Include `path_length` field for each ancestor
</ParamField>

<ParamField query="include_invalid" type="boolean" optional default="false">
  Include deprecated/invalid concepts in ancestry (by default they are excluded)
</ParamField>

<ParamField query="page" type="integer" optional default="1">
  Page number for pagination (1-based)
</ParamField>

<ParamField query="max_results" type="integer" optional default="5000">
  Maximum size of the ancestor set to retrieve before pagination is applied.

  <br />

  **Range:** `1-5000`

  <br />

  Defaults to the maximum, so paging through the response returns every ancestor
  **that matches this request** - those within `max_levels` and any `vocabulary_ids`
  / `domain_ids` filters you supplied. (`relationship_types` is not applied - see
  above.) It is not necessarily the concept's entire ancestry: `max_levels` defaults
  to `10`, so more distant ancestors are excluded, and `truncated` does **not** flag
  that (it reports the row cap only). Pass `max_levels=20` if you need the full
  ancestry.
</ParamField>

<ParamField query="page_size" type="integer" optional default="100">
  Number of ancestor concepts to return per page. Values above `200` are
  clamped to `200`.
</ParamField>

<ParamField query="vocab_release" type="string" optional>
  Specific vocabulary release version to query

  <br />

  **Example:** `2025.1`
</ParamField>

## Response

<ResponseField name="concept_id" type="integer">
  The concept ID for which ancestors were retrieved
</ResponseField>

<ResponseField name="concept_name" type="string">
  Standard name of the source concept
</ResponseField>

<ResponseField name="vocabulary_id" type="string">
  Vocabulary containing the source concept
</ResponseField>

<ResponseField name="ancestors" type="array">
  Array of ancestor concepts in hierarchical order

  <Expandable title="Ancestor Concept Object">
    <ResponseField name="concept_id" type="integer">
      Unique identifier for the ancestor concept
    </ResponseField>

    <ResponseField name="concept_name" type="string">
      Standard name of the ancestor concept
    </ResponseField>

    <ResponseField name="concept_code" type="string">
      Original code from the vocabulary
    </ResponseField>

    <ResponseField name="vocabulary_id" type="string">
      Vocabulary containing this ancestor concept
    </ResponseField>

    <ResponseField name="vocabulary_name" type="string">
      Human-readable vocabulary name
    </ResponseField>

    <ResponseField name="domain_id" type="string">
      Domain classification of the ancestor
    </ResponseField>

    <ResponseField name="concept_class_id" type="string">
      Concept class identifier
    </ResponseField>

    <ResponseField name="standard_concept" type="string">
      Standard concept designation ('S', 'C', or null)
    </ResponseField>

    <ResponseField name="level" type="integer">
      Distance from source concept (always present)
    </ResponseField>

    <ResponseField name="min_levels_of_separation" type="integer">
      Minimum levels of separation from source concept
    </ResponseField>

    <ResponseField name="max_levels_of_separation" type="integer">
      Maximum levels of separation from source concept
    </ResponseField>

    <ResponseField name="relationship_id" type="string">
      Relationship type ID (e.g., "Is a")
    </ResponseField>

    <ResponseField name="relationship_name" type="string">
      Relationship type name (e.g., "Is a")
    </ResponseField>

    <ResponseField name="hierarchy_level" type="integer" optional>
      Distance from source concept (only when include\_distance=true, same as level)
    </ResponseField>

    <ResponseField name="path_length" type="integer" optional>
      Path length from source concept (only when include\_paths=true, same as level)
    </ResponseField>

    <ResponseField name="valid_start_date" type="string">
      Date when concept became valid (ISO format)
    </ResponseField>

    <ResponseField name="valid_end_date" type="string">
      Date when concept became invalid (ISO format)
    </ResponseField>

    <ResponseField name="invalid_reason" type="string" optional>
      Reason for concept invalidation if applicable
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="hierarchy_summary" type="object">
  Summary statistics about the ancestor hierarchy

  <Expandable title="Hierarchy Summary Object">
    <ResponseField name="total_ancestors" type="integer">
      Total number of ancestor concepts found
    </ResponseField>

    <ResponseField name="max_hierarchy_depth" type="integer">
      Maximum depth of the hierarchy tree
    </ResponseField>

    <ResponseField name="unique_vocabularies" type="array">
      List of vocabulary IDs represented in ancestors
    </ResponseField>

    <ResponseField name="relationship_types_used" type="array">
      List of relationship type IDs found in hierarchy
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="meta" type="object">
  Response metadata and pagination information

  <Expandable title="Metadata Object">
    <ResponseField name="pagination" type="object">
      <ResponseField name="page" type="integer">Current page number</ResponseField>
      <ResponseField name="page_size" type="integer">Items per page</ResponseField>
      <ResponseField name="total_items" type="integer">Total ancestor concepts</ResponseField>
      <ResponseField name="total_pages" type="integer">Total number of pages</ResponseField>
      <ResponseField name="has_next" type="boolean">Whether next page exists</ResponseField>
      <ResponseField name="has_previous" type="boolean">Whether previous page exists</ResponseField>
    </ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X GET "https://api.omophub.com/v1/concepts/201826/ancestors?include_paths=true&include_distance=true&max_levels=5" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Accept: application/json"
  ```

  ```ts TypeScript theme={null}
  import { OMOPHub } from '@omophub/omophub-node';

  const client = new OMOPHub();
  const { data: ancestorData } = await client.hierarchy.ancestors(201826, {
    includePaths: true,
    includeDistance: true,
    maxLevels: 5,
  });

  console.log(`Found ${ancestorData?.hierarchy_summary.total_ancestors} ancestors`);
  console.log('First ancestor:', ancestorData?.ancestors[0]?.concept_name);
  ```

  ```python Python theme={null}
  import requests

  concept_id = 201826  # Type 2 diabetes mellitus
  url = f"https://api.omophub.com/v1/concepts/{concept_id}/ancestors"
  params = {
      "include_paths": True,
      "include_distance": True,
      "max_levels": 5
  }

  headers = {
      "Authorization": "Bearer YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  response = requests.get(url, params=params, headers=headers)
  ancestor_data = response.json()

  print(f"Concept: {ancestor_data['data']['concept_name']}")
  print(f"Total ancestors: {ancestor_data['data']['hierarchy_summary']['total_ancestors']}")

  for ancestor in ancestor_data['data']['ancestors'][:5]:
      level = ancestor.get('level', 'Unknown')
      print(f"Level {level}: {ancestor['concept_name']} ({ancestor['concept_id']})")
  ```
</RequestExample>

<ResponseExample>
  ```json theme={null}
  {
    "success": true,
    "data": {
      "concept_id": 201826,
      "concept_name": "Type 2 diabetes mellitus",
      "vocabulary_id": "SNOMED",
      "ancestors": [
        {
          "concept_id": 73211009,
          "concept_name": "Diabetes mellitus",
          "concept_code": "73211009",
          "vocabulary_id": "SNOMED",
          "vocabulary_name": "SNOMED Clinical Terms",
          "domain_id": "Condition",
          "concept_class_id": "Clinical Finding",
          "standard_concept": "S",
          "level": 1,
          "min_levels_of_separation": 1,
          "max_levels_of_separation": 1,
          "relationship_id": "Is a",
          "relationship_name": "Is a",
          "hierarchy_level": 1,
          "valid_start_date": "1970-01-01",
          "valid_end_date": "2099-12-31",
          "invalid_reason": null
        },
        {
          "concept_id": 362969004,
          "concept_name": "Disorder of endocrine system",
          "concept_code": "362969004",
          "vocabulary_id": "SNOMED",
          "vocabulary_name": "SNOMED Clinical Terms",
          "domain_id": "Condition",
          "concept_class_id": "Clinical Finding",
          "standard_concept": "S",
          "level": 2,
          "min_levels_of_separation": 2,
          "max_levels_of_separation": 2,
          "relationship_id": "Is a",
          "relationship_name": "Is a",
          "hierarchy_level": 2,
          "valid_start_date": "2002-01-31",
          "valid_end_date": "2099-12-31",
          "invalid_reason": null
        },
        {
          "concept_id": 64572001,
          "concept_name": "Disease",
          "concept_code": "64572001",
          "vocabulary_id": "SNOMED",
          "vocabulary_name": "SNOMED Clinical Terms",
          "domain_id": "Condition",
          "concept_class_id": "Clinical Finding",
          "standard_concept": "S",
          "level": 3,
          "min_levels_of_separation": 3,
          "max_levels_of_separation": 3,
          "relationship_id": "Is a",
          "relationship_name": "Is a",
          "hierarchy_level": 3,
          "valid_start_date": "1970-01-01",
          "valid_end_date": "2099-12-31",
          "invalid_reason": null
        }
      ],
      "hierarchy_summary": {
        "total_ancestors": 3,
        "max_hierarchy_depth": 3,
        "unique_vocabularies": ["SNOMED"],
        "relationship_types_used": ["Is a"]
      }
    },
    "meta": {
      "pagination": {
        "page": 1,
        "page_size": 100,
        "total_items": 3,
        "total_pages": 1,
        "has_next": false,
        "has_previous": false
      },
      "request_id": "req_ancestors_201826_20250104_103100",
      "timestamp": "2025-01-04T10:31:00Z",
      "vocab_release": "2025.1"
    }
  }
  ```
</ResponseExample>

## Usage Examples

### Basic Ancestor Retrieval

Get all ancestors for a specific concept:

```ts TypeScript theme={null}
const { data: ancestors } = await client.hierarchy.ancestors(201826);
```

### Limited Hierarchy Depth

Retrieve ancestors up to a specific number of levels:

```ts TypeScript theme={null}
const { data: nearAncestors } = await client.hierarchy.ancestors(201826, { maxLevels: 3 });
```

### Classification Path Analysis

Get complete classification paths from concept to root:

```ts TypeScript theme={null}
const { data: pathData } = await client.hierarchy.ancestors(201826, {
  includePaths: true,
  includeDistance: true,
});
```

### Cross-Vocabulary Hierarchy

Analyze ancestors within specific vocabulary:

```ts TypeScript theme={null}
const { data: snomedAncestors } = await client.hierarchy.ancestors(201826, {
  vocabularyIds: ['SNOMED'],
});
```

### Multiple Relationship Types

Follow different types of hierarchical relationships:

```ts TypeScript theme={null}
const { data: extendedHierarchy } = await client.hierarchy.ancestors(201826, {
  relationshipTypes: ['Is a', 'Part of'],
});
```

## Related Endpoints

* [Get Concept Descendants](/api-reference/hierarchy/get-concept-descendants) - Retrieve child concepts
* [Get Concept Hierarchy](/api-reference/hierarchy/get-concept-hierarchy) - Complete hierarchy view
* [Get Concept Relationships](/api-reference/relationships/get-concept-relationships) - All concept relationships
* [Get Concept Details](/api-reference/concepts/get-concept-details) - Complete concept information

## Notes

* Hierarchy traversal follows "Is a" relationships by default, but can be customized
* Some concepts may have multiple classification paths to different root concepts
* Cross-vocabulary concepts may have ancestors in different vocabularies
* Standard concepts are prioritized in hierarchy traversal unless explicitly disabled
* Deprecated concepts are excluded from ancestry unless specifically requested
* Maximum hierarchy depth is typically 6-8 levels for most medical vocabularies
