---
title: "MERCURY Verifiable Web Fetch"
method: GET
path: "/buy/fetch"
tags: ["verifiable-web-fetch", "agent-web-fetch", "web-fetch", "attestation", "provenance", "structured-extract", "data-feed", "verifiable-data-record", "agent-data", "market-data-adjacent", "scraping", "rag", "keyless", "agent-native"]
---

# MERCURY Verifiable Web Fetch

`GET /buy/fetch`

## Request

- Base URL: `https://network.mercury-hq.com`
- URL: `https://network.mercury-hq.com/buy/fetch`
- Auth: none declared
- TypeScript: <https://skmtc.dev/mercury-hq/apis/mercury-x402-storefront/docs/buy/fetch/get.ts> (a function with typed inputs; its response is checked against the schema)

VERIFIABLE keyless web-read for autonomous agents. Every result ships a cryptographically SIGNED provenance receipt (EIP-191 over sha256(text)+url+status+time) — the wedge a free scraper structurally CANNOT match: Jina r.jina.ai is free+keyless too, but its bytes are HEARSAY (no proof of what/where/when). MERCURY's `attestation` is ecrecoverable OFFLINE, forever, by you OR any downstream agent you forward the bytes to — proving the content is genuine + untampered (key pinned at /.well-known/mercury-attestation). For RAG, trading and agent-to-agent commerce that need provenance, that is the gap between data and evidence. Beyond that it's the keyless web-read primitive — NO API key, NO signup, NO account, NO monthly plan, the one fetch SKU a fresh agent can onboard to by itself instead of stopping to ask a human for a key. Give a ?url= and get back clean readable page text + title + status. Agent-native extras (opt-in): ?format=markdown for structure-preserving markdown, ?links=1 for an outbound-link graph (crawl frontier), and the headline wedge — STRUCTURED EXTRACT: ?extract=title,price,author,publishedAt returns a clean JSON record { title, price, author, publishedAt }, an LLM-ready row not a wall of text. That is Firecrawl's paid 'JSON mode' (they need an LLM call + an API key for it) done here DETERMINISTICALLY from the page's own JSON-LD/OpenGraph/meta/microdata — keyless, no LLM, $0.003. (?extract=1 still returns the legacy description + wordCount.) The extracted record is folded into the SIGNED attestation too, so a buyer can prove the FIELDS — not just the raw bytes — are exactly what MERCURY resolved. You pay in-band over HTTP 402 (x402, USDC on Base mainnet) — the wedge those tools can't match: they ALL gate behind a human-created API key + a credit-card plan, so an agent can't onboard itself. This one an agent finds in the x402 Bazaar and pays with zero human in the loop. Honest charge-per-ATTEMPT: every call returns a structured result (success OR an ok:false failure with a reason) — never a silent charge-then-500. Follows redirects, SSRF-guarded, 5s timeout, 10MB cap. Pure data, no mint — delivers in prod.

## Query parameters

- `url` string, required: the page to fetch (http/https)
- `format` 'text' | 'markdown': text (default) or structure-preserving markdown
- `links` '0' | '1': 1 = also return the outbound-link graph (crawl frontier)
- `extract` string: 1 = page description + wordCount; OR a comma-list of field names (e.g. title,price,author,publishedAt) to get a structured JSON record under `extract`

## Response `200`

Delivered after the x402 payment settles on Base mainnet.

- object
  - `ok` boolean, required: true on success; false on an honest failure (still delivered)
  - `url` string, required: final URL after redirects
  - `status` integer: upstream HTTP status
  - `title` string: page <title> (HTML pages only)
  - `text` string: cleaned, readable page text (or markdown if ?format=markdown)
  - `format` 'markdown': echoed only when ?format=markdown was requested
  - `description` string: page meta/og description (only when ?extract=1)
  - `wordCount` integer: word count of returned text (only when ?extract=1)
  - `extract` object: STRUCTURED JSON record (only when ?extract=<comma-list of fields>). The Firecrawl-JSON-mode wedge: each requested field resolved from JSON-LD/OpenGraph/meta/microdata, absent fields null. Deterministic, keyless, no LLM call. The signed attestation covers this record too.
  - `links` object[]: outbound-link graph, same-origin first (only when ?links=1)
    - `url` string
    - `text` string
  - `contentType` string
  - `bytes` integer: raw body size
  - `truncated` boolean
  - `error` string: present only when ok:false
  - `attestation` object: EIP-191 provenance receipt: a signature over sha256(text)+url+status+time, verifiable OFFLINE by anyone (key pinned at /.well-known/mercury-attestation). Proves the content is genuine + untampered — the non-commodity edge of a signed-payment seller.
    - `keyId` string: versioned key id (scheme + signer address)
    - `alg` string: EIP-191-personal_sign
    - `address` string: the signer address; recover() must equal this
    - `contentHash` string: 0x… sha256 hex of `text`
    - `nonce` string
    - `signedAt` string
    - `signature` string: 0x… 65-byte EIP-191 signature
    - `verify` object: the exact signed `message` + a one-line howTo, so verification needs no MERCURY SDK
      - `message` string
      - `howTo` string

## Other responses

- `402`: Payment Required — retry with an x402-signed payment (e.g. x402-fetch). Terms are in the challenge body (x402 v1).

---

[API](https://skmtc.dev/mercury-hq/apis/mercury-x402-storefront.md) - [All operations](https://skmtc.dev/mercury-hq/apis/mercury-x402-storefront/llms.txt) - [OpenAPI document](https://skmtc.dev/mercury-hq/apis/mercury-x402-storefront/revisions/211aa7db24ae?raw)
