---
title: "Decision: Inline graph_data in bundle URLs"
url: https://mdfy.app/yIpXMsqc
updated: 2026-05-14T18:15:49.480Z
source: "mdfy.app"
---
# Decision: Inline graph_data in bundle URLs

> Companion to the public spec version at /spec. This is the engineering-side version with the receipts.

## What we do

Every bundle URL (e.g. `mdfy.app/b/wpwVCSDF`) returns markdown with the bundle's `graph_data` JSON inlined as a fenced code block at the top of the response. The receiving AI fetches the URL once and inherits themes, insights, document summaries, and the concept graph in a single round trip.

## The alternative we rejected

Lazy / on-demand: ship the URL with just the doc list, let the caller pull `/api/bundles/{id}/graph` separately if they want analysis.

That's simpler. We chose against it because:

1. **AI agents don't make a second call by default.** Claude Code, Cursor, Codex all fetch a URL once and consume what they get. If the analysis isn't in the response, they don't see it.
2. **The graph is small.** Median ~3KB per bundle. We measured. Pasting a 3KB JSON block into a 100KB doc response is a 3% size hit and a 0% latency hit.
3. **The graph is the differentiator.** Without it, mdfy bundles look like "a list of markdown files concatenated." With it, they look like "synthesised intelligence." We want every AI on the planet to see the second.

## The query knobs

We added two `?` params so callers can dial cost:

- `?graph=0` — omit the graph_data block (recall scenarios where the model just wants the prose)
- `?full=1` — inline every member doc inside the response (max-context scenarios)

Default is `graph_data inlined, member docs as URL stubs.`

## What this commits us to

Bundle analysis has to stay current. The "stale" badge on the analysed pill in the UI is the user-visible commitment to keep it that way. Auto-analyse on member-doc changes is Pro-only; free tier sees the badge and clicks "Re-analyse" manually.
