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

# Examples

> Copy-paste Riftmap API examples in curl, Python, and TypeScript: resolve a repo, hydrate context, compute blast radius, and walk the dependency subgraph.

The four most common agent flows, end‑to‑end. Every snippet expects two environment variables:

```bash theme={null}
RIFTMAP_API_KEY=rfm_live_xxx
RIFTMAP_BASE_URL=https://api.riftmap.dev/api/v1
```

The Python examples use `httpx` (async). The TypeScript examples use the runtime‑native `fetch` (Node 22+ / modern browsers).

***

## 1. Resolve a clone URL

The agent has a working tree at `github.com/myorg/payments-api` and needs to find the corresponding Riftmap repo.

<CodeGroup>
  ```bash curl theme={null}
  curl -s "$RIFTMAP_BASE_URL/repositories/lookup?url=https://github.com/myorg/payments-api" \
    -H "X-API-Key: $RIFTMAP_API_KEY"
  ```

  ```python Python theme={null}
  import os
  import httpx

  BASE = os.environ["RIFTMAP_BASE_URL"]
  HEADERS = {"X-API-Key": os.environ["RIFTMAP_API_KEY"]}

  async def lookup(clone_url: str) -> dict | None:
      async with httpx.AsyncClient(headers=HEADERS, timeout=10) as client:
          r = await client.get(f"{BASE}/repositories/lookup", params={"url": clone_url})
          if r.status_code == 404:
              return None
          r.raise_for_status()
          return r.json()
  ```

  ```typescript TypeScript theme={null}
  const BASE = process.env.RIFTMAP_BASE_URL!;
  const HEADERS = { "X-API-Key": process.env.RIFTMAP_API_KEY! };

  export async function lookup(cloneUrl: string) {
    const url = new URL(`${BASE}/repositories/lookup`);
    url.searchParams.set("url", cloneUrl);
    const r = await fetch(url, { headers: HEADERS });
    if (r.status === 404) return null;
    if (!r.ok) throw new Error(`lookup failed: ${r.status}`);
    return r.json();
  }
  ```
</CodeGroup>

Returns the repo row including freshness fields. Use `full_path=myorg/payments-api` instead of `url=` if you only have the slug.

***

## 2. Hydrate context in one round‑trip

Once you have the repo ID, fetch repo + capped dependencies + capped dependents + artifacts + a slim ownership summary in a single call.

<CodeGroup>
  ```bash curl theme={null}
  curl -s "$RIFTMAP_BASE_URL/repositories/$REPO_ID/context" \
    -H "X-API-Key: $RIFTMAP_API_KEY"
  ```

  ```python Python theme={null}
  async def get_context(repo_id: str) -> dict:
      async with httpx.AsyncClient(headers=HEADERS, timeout=15) as client:
          r = await client.get(f"{BASE}/repositories/{repo_id}/context")
          r.raise_for_status()
          ctx = r.json()
      # Freshness check
      repo = ctx["repository"]
      if repo["last_activity_at"] and repo["last_scanned_at"]:
          if repo["last_activity_at"] > repo["last_scanned_at"]:
              print(f"WARN: stale data for {repo['full_path']}")
      return ctx
  ```

  ```typescript TypeScript theme={null}
  export async function getContext(repoId: string) {
    const r = await fetch(`${BASE}/repositories/${repoId}/context`, { headers: HEADERS });
    if (!r.ok) throw new Error(`context failed: ${r.status}`);
    const ctx = await r.json();
    const { last_activity_at, last_scanned_at, full_path } = ctx.repository;
    if (last_activity_at && last_scanned_at && last_activity_at > last_scanned_at) {
      console.warn(`stale data for ${full_path}`);
    }
    return ctx;
  }
  ```
</CodeGroup>

Use `dependencies_total` and `dependents_total` to detect when you need to paginate the full lists separately (the bundled arrays are capped at 100).

***

## 3. Compute the transitive blast radius

When you actually need to know "if I change repo A, what *transitively* breaks?", call `/impact`. This runs a Python BFS over confidence‑filtered edges.

<CodeGroup>
  ```bash curl theme={null}
  curl -s "$RIFTMAP_BASE_URL/repositories/$REPO_ID/impact?max_depth=3&min_confidence=0.8" \
    -H "X-API-Key: $RIFTMAP_API_KEY"
  ```

  ```python Python theme={null}
  async def impact(repo_id: str, max_depth: int = 3, min_confidence: float = 0.8) -> dict:
      async with httpx.AsyncClient(headers=HEADERS, timeout=20) as client:
          r = await client.get(
              f"{BASE}/repositories/{repo_id}/impact",
              params={"max_depth": max_depth, "min_confidence": min_confidence},
          )
          r.raise_for_status()
          return r.json()

  # Result shape: { source_repository, affected_repositories: [{id, name, full_path, depth, confidence}], total_affected, max_depth_reached }
  ```

  ```typescript TypeScript theme={null}
  export async function impact(repoId: string, maxDepth = 3, minConfidence = 0.8) {
    const url = new URL(`${BASE}/repositories/${repoId}/impact`);
    url.searchParams.set("max_depth", String(maxDepth));
    url.searchParams.set("min_confidence", String(minConfidence));
    const r = await fetch(url, { headers: HEADERS });
    if (!r.ok) throw new Error(`impact failed: ${r.status}`);
    return r.json();
  }
  ```
</CodeGroup>

`max_depth` defaults to 10 (range 1–20). `min_confidence` defaults to 0.8 — drop to 0.5 if you want to include heuristic matches in the radius.

***

## 4. Walk the local subgraph

For visualisation, or for an agent that wants the local neighbourhood rather than the full transitive set, request a subgraph anchored at a repo.

<CodeGroup>
  ```bash curl theme={null}
  curl -s "$RIFTMAP_BASE_URL/connected-orgs/$ORG_ID/graph?root=$REPO_ID&depth=2&min_confidence=0.8" \
    -H "X-API-Key: $RIFTMAP_API_KEY"
  ```

  ```python Python theme={null}
  async def subgraph(org_id: str, root_repo_id: str, depth: int = 2) -> dict:
      async with httpx.AsyncClient(headers=HEADERS, timeout=15) as client:
          r = await client.get(
              f"{BASE}/connected-orgs/{org_id}/graph",
              params={"root": root_repo_id, "depth": depth, "min_confidence": 0.8},
          )
          r.raise_for_status()
          return r.json()
  ```

  ```typescript TypeScript theme={null}
  export async function subgraph(orgId: string, rootRepoId: string, depth = 2) {
    const url = new URL(`${BASE}/connected-orgs/${orgId}/graph`);
    url.searchParams.set("root", rootRepoId);
    url.searchParams.set("depth", String(depth));
    url.searchParams.set("min_confidence", "0.8");
    const r = await fetch(url, { headers: HEADERS });
    if (!r.ok) throw new Error(`graph failed: ${r.status}`);
    return r.json();
  }
  ```
</CodeGroup>

Returns `{ nodes: [{id, type, label, metadata: {archived, last_activity_at, health_status, …}}], edges: [{source, target, dependency_type, version_constraint, confidence}] }`. The shape is G6‑ready, but plain enough to drive any visualisation library.

***

## Pagination

For `dependencies` / `dependents` lists past 100 items:

<CodeGroup>
  ```bash curl theme={null}
  # First page
  curl -s -D - "$RIFTMAP_BASE_URL/repositories/$REPO_ID/dependents?limit=500&offset=0" \
    -H "X-API-Key: $RIFTMAP_API_KEY"
  # Inspect X-Total-Count in headers; loop with offset += 500.
  ```

  ```python Python theme={null}
  async def all_dependents(repo_id: str) -> list[dict]:
      out, offset, limit = [], 0, 500
      async with httpx.AsyncClient(headers=HEADERS, timeout=20) as client:
          while True:
              r = await client.get(
                  f"{BASE}/repositories/{repo_id}/dependents",
                  params={"limit": limit, "offset": offset},
              )
              r.raise_for_status()
              page = r.json()
              out.extend(page)
              total = int(r.headers.get("X-Total-Count", len(out)))
              offset += limit
              if offset >= total:
                  return out
  ```

  ```typescript TypeScript theme={null}
  export async function allDependents(repoId: string) {
    const out: unknown[] = [];
    let offset = 0;
    const limit = 500;
    while (true) {
      const url = new URL(`${BASE}/repositories/${repoId}/dependents`);
      url.searchParams.set("limit", String(limit));
      url.searchParams.set("offset", String(offset));
      const r = await fetch(url, { headers: HEADERS });
      if (!r.ok) throw new Error(`dependents failed: ${r.status}`);
      out.push(...(await r.json()));
      const total = Number(r.headers.get("X-Total-Count") ?? out.length);
      offset += limit;
      if (offset >= total) return out;
    }
  }
  ```
</CodeGroup>

***

## Errors agents should handle

| Status | Meaning                                         | Recommended action                                                      |
| ------ | ----------------------------------------------- | ----------------------------------------------------------------------- |
| `401`  | Missing or invalid API key                      | Surface to user; never retry.                                           |
| `404`  | Repo not in this workspace, or never scanned    | Try `lookup` with the alternate parameter; fall back to "unknown repo". |
| `409`  | Lookup matched multiple repos                   | Disambiguate using `full_path`.                                         |
| `422`  | Out‑of‑range pagination, or invalid query param | Fix the request; do not retry.                                          |
| `429`  | Rate limit (mutations only)                     | Honour `Retry-After` header before retrying.                            |
