---
title: Graph Traverse
description: Walk the citation graph between documents — cites, amends, repeals, implements, interprets.
order: 3
---

`POST /v1/graph/traverse`

Iterative BFS over the `legal_edges` collection, batched per level — no `$graphLookup`. Depth is capped at 3.

A `direction: "both"`, `depth: 1` call from `eg-leg-1948-131` (Egypt's Civil Code) returns something like:

```mermaid
flowchart LR
    R["eg-cass-civ-1995-1234<br/>(cassation ruling)"] -- cites --> C["eg-leg-1948-131<br/>Civil Code"]
    C -- amends --> A["eg-leg-2021-45<br/>(later amendment)"]
    C -- repeals --> P["eg-leg-1937-58<br/>(prior code, superseded)"]
```

`eg-leg-1948-131` is the `canonical_id` you queried; everything one hop out in either direction comes back as a hydrated node plus the edge connecting it. Raising `depth` walks further out, one BFS level at a time.

## Request

```json
{
  "canonical_id": "eg-leg-1948-131",
  "direction": "both",
  "edge_types": ["cites", "amends"],
  "depth": 1,
  "limit": 100
}
```

| Field | Type | Default | Notes |
|---|---|---|---|
| `canonical_id` | string | required | |
| `direction` | string | required | `in`, `out`, or `both` |
| `edge_types` | string[] | all | `cites`, `amends`, `repeals`, `implements`, `interprets` |
| `depth` | integer | `1` | 1–3 |
| `limit` | integer | `100` | 1–100 |

## Response

```json
{
  "nodes": [
    { "canonical_id": "eg-leg-1948-131", "title": "القانون المدني", "doc_type": "legislation", "year": 1948, "status": "in_force" }
  ],
  "edges": [
    { "from_id": "eg-cass-civ-1995-1234", "to_id": "eg-leg-1948-131", "edge_type": "cites", "article_ref": "163", "confidence": 0.97 }
  ]
}
```

Nodes are hydrated (title/doc_type/year/status included), not just bare IDs — no follow-up `/v1/document` call needed to render a graph view. `edges[].confidence` reflects the citation-extraction model's confidence in that edge, not a relevance score.

## Errors

- `401 unauthorized`
- `422 validation_error`
- `503 upstream_unavailable`
