Understand the Markdown and JSON shapes returned by Fetch.
Fetch has two primary output views: a Markdown document for agents and a structured JSON Mode response for applications. Both carry the same capture, split differently: frontmatter/meta, Main Markdown, State JSON, Appendix references, snapshot handles, and evidence.
Markdown mode
POST /v1/fetch
-> text/markdown
JSON Mode
POST /v1/fetch/json
-> { meta, markdown, json, data }curl https://api.expand.ai/v1/fetch \
-H "x-expand-api-key: $EXPAND_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://news.ycombinator.com"}'Next: See Include Options to control which fields come back, for exact schemas, or read for the capture model behind these fields.
POST /v1/fetch returns a Markdown document, not JSON. The document opens with YAML frontmatter and is followed by the Main Markdown body.
---
version: 1
url: https://example.com
capturedAt: 2026-06-24T...
snapshotId: ...
playground: https://expand.land/s/...
title: ...
stateJson:
moreTokens: 1200
appendix:
url: ...
links:
sameDomain: 42
external: 7
---
# Main page title
Main Markdown body...meta. Same values, expressed as YAML.snapshotId is the stable handle for follow-up retrieval, Highlights, citations, and replay.playground is the whole-capture inspection link, openable at https://expand.land/s/<snapshotId>.stateJson, appendix, and markdown in frontmatter can be references or hints to more content rather than the content itself.?include= controls whether Markdown mode embeds State JSON and Appendix directly. The full request controls live in Include Options.Frontmatter has more fields than shown here. See the API Reference for the exact schema instead of relying on this sketch.
POST /v1/fetch/json returns the same capture as named fields an application can read directly.
{
meta: {
version: 1,
url: string,
capturedAt: string,
snapshotId: string,
playground: string,
title?: string,
finalUrl?: string,
appendix?: { url: string, links: { sameDomain: number, external: number } },
stateJson?: { moreTokens: number },
markdown?: { url: string, moreTokens: number },
blocked?: string,
loadingStatus?: string
},
markdown: string,
json: [
{
id: number,
kind: "inline" |
meta is the frontmatter expressed as JSON.markdown is the Main Markdown body without frontmatter or evidence sections.json is State JSON evidence, one entry per preserved source.url and captured HTTP method when available.urlRedacted: true means credentials were removed from the URL; urlOmitted explains why no URL was disclosed.data.search holds Highlights results when you request them.meta.appendix, meta.stateJson, and meta.markdown are references to more, not the content itself.JSON Mode is not a different capture. It is the same Fetch output split into fields for applications.
State JSON is called json on the wire because it is data. In docs, State JSON means the selected page and network state Fetch preserved for reasoning.
Product names map to specific wire fields and surfaces. This table resolves the naming, it does not add a new layer.
| Product term | Field / surface |
|---|---|
| Main Markdown | markdown |
| Frontmatter | Markdown YAML frontmatter / JSON Mode meta |
| State JSON | json, meta.stateJson, include=json, statejson in Markdown ?include= |
When output would be too large or secondary to the main task, Fetch returns a reference instead of flooding the response.
You will see references in fields like:
meta.stateJson.moreTokensmeta.appendix.urlmeta.markdown.urljson[].moreTokensjson[].keyssnapshotIdplaygroundReferences are not missing data. They are stable paths back to the capture when the task needs more depth. Follow them with Highlights or by opening the snapshot in Playground & Replay.
Evidence lives at the field level in Fetch output. Raw API Highlights snippets may include:
sourcetextscorejsonlocationMCP and SDK helpers may add:
citationUrlcitationUrl is added by MCP tooling and SDK helpers. Raw API responses expose the location data needed to build citation links.
For snippet retrieval, see Highlights. For citation inspection and auditing, see Playground & Replay. For exact snippet schemas, see the API Reference.
A synchronous POST /v1/fetch can return a FetchBlocked error when a page cannot be captured. In JSON Mode, meta.blocked or meta.loadingStatus may appear on short-circuited or partial responses, and batched results can carry per-item blocked state.
These fields signal capture state only. For why a capture was blocked or partial, see Browser Behavior and the API Reference.
| Appendix | appendix, meta.appendix, include=appendix |
| Highlights | data.search, /v1/fetch/search, fetch_search, expandai search |
| Evidence ID | json[].id, location.evidenceId, citation URLs |
| Snapshot | snapshotId, meta.playground |