> For the complete documentation index, see [llms.txt](https://docs.opendatadiscovery.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.opendatadiscovery.org/developer-guides/api-reference/lineage.md).

# Lineage

Lineage covers both data-object lineage (datasets and views, transformers, transformer runs, data-quality tests, consumers, data inputs, entity groups, and the relationships between them — see [Data Objects Lineage](/features/data-lineage/data-objects.md)) and microservices lineage ([Microservices Lineage](/features/data-lineage/microservices.md)). Both surfaces are backed by the same three endpoints below — entity-class participation is determined by what the data sources have ingested, not by a separate API. For the canonical class reference, see the [ODD Data Model](https://github.com/opendatadiscovery/opendatadiscovery-specification/blob/main/specification/specification.md#data-model-specification).

{% hint style="warning" %}
**Lineage reads are not access-controlled per owner.** None of the lineage endpoints on this page applies an ownership filter or requires a permission beyond being signed in. Any authenticated user who knows a data-entity id or group id can read the full reachable lineage subgraph around it, across all teams. When the platform runs with `auth.type=DISABLED`, the sign-in requirement is removed from every endpoint — these reads become reachable by any unauthenticated client on the network. The **group-lineage** endpoint has the widest reach: walking group ids enumerates the cross-owner co-membership graph of the whole catalog. See [Authorization](/configuration-and-deployment/enable-security/authorization.md) for the platform-wide model.
{% endhint %}

**Per-entity lineage**

| Method | Path                                                    | Operation ID                     | Purpose                                                                                          |
| ------ | ------------------------------------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------ |
| `GET`  | `/api/dataentities/{data_entity_id}/lineage/upstream`   | `getDataEntityUpstreamLineage`   | Returns the upstream lineage graph rooted at the given data entity (everything that feeds it).   |
| `GET`  | `/api/dataentities/{data_entity_id}/lineage/downstream` | `getDataEntityDownstreamLineage` | Returns the downstream lineage graph rooted at the given data entity (everything it feeds into). |

Both endpoints accept the same two optional query parameters that control the shape of the returned graph:

| Parameter             | Type                                  | Behaviour                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| --------------------- | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `lineage_depth`       | `integer` *(minimum `1`, no maximum)* | Number of hops to traverse from the rooted entity. The platform UI's depth dropdown (1 to 20) is a **UI-presentation choice only** — the controller validates `@Min(1)` but has no `@Max`, the service tier hands the value through unchanged, and the repository tier consumes it directly as the recursive-CTE termination predicate. Direct API callers can pass any positive integer; very large values trigger correspondingly expensive recursive walks against the platform's Postgres backend. Lower values give a quick neighbourhood view; higher values follow cross-system pipelines end-to-end at the cost of a larger response payload. **`lineage_depth` is required in practice even though the spec marks it optional:** the endpoints have no default, so omitting it makes the platform throw a `NullPointerException` and return **HTTP 500** before any graph is built — not a default-depth graph. Always pass an explicit value. See [Data Objects Lineage → Lineage depth — UI control vs API contract](/features/data-lineage/data-objects.md#lineage-depth--ui-control-vs-api-contract) for the operator-facing framing. |
| `expanded_entity_ids` | `array of integer` *(repeatable)*     | IDs of `Data Entity Group` entities that should be expanded inline in the response. By default groups appear as a single collapsed node; passing a group's ID here drills into that one group for the request without expanding any others.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |

**Group lineage**

| Method | Path                                                   | Operation ID                 | Purpose                                                                                                                                                                                                                                                                 |
| ------ | ------------------------------------------------------ | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET`  | `/api/dataentitygroups/{data_entity_group_id}/lineage` | `getDataEntityGroupsLineage` | Returns the lineage graph **for the group's children** — i.e. the lineage relationships among the entities that belong to the given group. Use it to inspect what a group aggregates without first expanding each member entity through the per-entity endpoints above. |

{% hint style="info" %}
**The group-lineage endpoint accepts no shape parameters today.** Unlike the per-entity endpoints above, `GET /api/dataentitygroups/{id}/lineage` carries **only the path parameter** — no `lineage_depth`, no `expanded_entity_ids`. Operators familiar with the per-entity API tend to try `?lineage_depth=5` against the group endpoint; the parameter is silently ignored. The depth and expansion behaviour on group lineage is platform-determined and cannot be tuned from the request.
{% endhint %}

{% hint style="info" %}
**Group lineage drops edges that touch a nested group.** Any lineage edge where either endpoint is itself a Data Entity Group is filtered out of the group-lineage response, and the nested groups are removed from the result — a group that contains other groups returns those nested groups missing, with no signal in the payload. Support for nested groups in group lineage is not implemented yet. The group view also keeps only edges whose **both** endpoints are members of the group, so an upstream source or downstream consumer that sits outside the group is not returned here; use the per-entity endpoints on a member to see across the group boundary.
{% endhint %}

{% hint style="warning" %}
**Empty Data Entity Group → HTTP 404. The sibling membership endpoint returns HTTP 200 with an empty list on the same condition.** Calling `GET /api/dataentitygroups/{id}/lineage` returns the identical `404 Not Found` for **three** distinct conditions: the id does not exist, the group exists but has zero members, or the id belongs to a data entity that is **not** a group at all. You cannot tell them apart from the response.

The membership-shaped sibling `GET /ingestion/entities/{degOddrn}/children` returns **200 OK with an empty `items: []`** on the same empty-DEG condition. A reconciliation script polling both endpoints against the same DEG ODDRN sees two different contracts for the same semantic state:

Clients consuming both must branch on this asymmetry. The upstream fix aligns the two endpoints (the default direction is the membership endpoint returning 404 on missing DEG so both endpoints have symmetric semantics); until it lands, treat the 404 from the lineage endpoint as "the id does not exist, is not a group, or is a group with no members" and disambiguate by polling the membership endpoint.
{% endhint %}

| Endpoint                                      | Empty DEG response        | Missing DEG response                              |
| --------------------------------------------- | ------------------------- | ------------------------------------------------- |
| `GET /api/dataentitygroups/{id}/lineage`      | `404 Not Found`           | `404 Not Found`                                   |
| `GET /ingestion/entities/{degOddrn}/children` | `200 OK` with `items: []` | (collector-side; payload validation tier handles) |

**My objects' upstream / downstream neighbours**

These two endpoints are scoped to the signed-in user via their owned entities. Both are paginated (`page`, `size`) and take no other parameters.

| Method | Path                              | Operation ID                 | Purpose                                                  |
| ------ | --------------------------------- | ---------------------------- | -------------------------------------------------------- |
| `GET`  | `/api/dataentities/my/upstream`   | `getMyObjectsWithUpstream`   | Entities **one hop upstream** of the entities you own.   |
| `GET`  | `/api/dataentities/my/downstream` | `getMyObjectsWithDownstream` | Entities **one hop downstream** of the entities you own. |

{% hint style="warning" %}
**These return your neighbours, not your own objects — and the response excludes the objects you own.** Despite the OpenAPI summary ("data entities owned by current user with … dependencies"), the platform computes the set of entities you own, walks one lineage hop up- or down-stream, and then **removes your own entities** from the result. So `GET /api/dataentities/my/downstream` answers "what consumes the things I own" (the non-owned downstream neighbours), not "which of my objects have downstream consumers." If you want your own objects annotated with whether they have upstream / downstream links, this is not that endpoint — use the per-entity lineage endpoints on each owned id instead.
{% endhint %}

## See also

* [API Reference hub](/developer-guides/api-reference.md) — the full per-feature index.
* [Data Objects Lineage](/features/data-lineage/data-objects.md) — data-object lineage feature description.
* [Microservices Lineage](/features/data-lineage/microservices.md) — microservices lineage feature description.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.opendatadiscovery.org/developer-guides/api-reference/lineage.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
