MERCURY
UniversityDocsFetchVerifiable Web Fetch

Mercury · Verifiable Web Fetch

Fetch$0.003 / callLivex402API key

GET /buy/fetch

What it does

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.

The goal it serves: give an agent provable web content — the bytes PLUS a portable, offline-verifiable proof of what/where/when — so RAG stores, research pipelines and downstream agents can cite evidence, not hearsay.

Schemas & output preview

Input schema — the exact request shape the route validates.

json · input schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "maxLength": 2048,
      "description": "the page to fetch (http/https)"
    },
    "format": {
      "type": "string",
      "enum": [
        "text",
        "markdown"
      ],
      "description": "text (default) or structure-preserving markdown"
    },
    "links": {
      "type": "string",
      "enum": [
        "0",
        "1"
      ],
      "description": "1 = also return the outbound-link graph (crawl frontier)"
    },
    "extract": {
      "type": "string",
      "maxLength": 256,
      "description": "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`"
    }
  },
  "required": [
    "url"
  ],
  "additionalProperties": false
}

Output schema — the exact response shape the handler returns.

json · output schema
{
  "type": "object",
  "properties": {
    "ok": {
      "type": "boolean",
      "description": "true on success; false on an honest failure (still delivered)"
    },
    "url": {
      "type": "string",
      "description": "final URL after redirects"
    },
    "status": {
      "type": "integer",
      "description": "upstream HTTP status"
    },
    "title": {
      "type": "string",
      "description": "page <title> (HTML pages only)"
    },
    "text": {
      "type": "string",
      "description": "cleaned, readable page text (or markdown if ?format=markdown)"
    },
    "format": {
      "type": "string",
      "enum": [
        "markdown"
      ],
      "description": "echoed only when ?format=markdown was requested"
    },
    "description": {
      "type": "string",
      "description": "page meta/og description (only when ?extract=1)"
    },
    "wordCount": {
      "type": "integer",
      "description": "word count of returned text (only when ?extract=1)"
    },
    "extract": {
      "type": "object",
      "description": "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.",
      "additionalProperties": {
        "type": [
          "string",
          "number",
          "boolean",
          "null"
        ]
      }
    },
    "links": {
      "type": "array",
      "description": "outbound-link graph, same-origin first (only when ?links=1)",
      "items": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "text": {
            "type": "string"
          }
        }
      }
    },
    "contentType": {
      "type": "string"
    },
    "bytes": {
      "type": "integer",
      "description": "raw body size"
    },
    "truncated": {
      "type": "boolean"
    },
    "error": {
      "type": "string",
      "description": "present only when ok:false"
    },
    "attestation": {
      "type": "object",
      "description": "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.",
      "properties": {
        "keyId": {
          "type": "string",
          "description": "versioned key id (scheme + signer address)"
        },
        "alg": {
          "type": "string",
          "description": "EIP-191-personal_sign"
        },
        "address": {
          "type": "string",
          "description": "the signer address; recover() must equal this"
        },
        "contentHash": {
          "type": "string",
          "description": "0x… sha256 hex of `text`"
        },
        "nonce": {
          "type": "string"
        },
        "signedAt": {
          "type": "string"
        },
        "signature": {
          "type": "string",
          "description": "0x… 65-byte EIP-191 signature"
        },
        "verify": {
          "type": "object",
          "description": "the exact signed `message` + a one-line howTo, so verification needs no MERCURY SDK",
          "properties": {
            "message": {
              "type": "string"
            },
            "howTo": {
              "type": "string"
            }
          }
        }
      }
    }
  },
  "required": [
    "ok",
    "url"
  ],
  "additionalProperties": false
}

Output preview — a real example response, shown free (you only pay when you call the route).

json · output preview
{
  "ok": true,
  "url": "https://example.com/",
  "status": 200,
  "title": "Example Domain",
  "format": "markdown",
  "text": "Example Domain\n\n# Example Domain\n\nThis domain is for use in documentation examples without needing permission. Avoid use in operations. [Learn more](https://iana.org/domains/example)",
  "description": "Example Domain # Example Domain This domain is for use in documentation examples without needing permission.",
  "wordCount": 22,
  "extract": {
    "title": "Example Domain",
    "price": null,
    "author": null
  },
  "links": [
    {
      "url": "https://iana.org/domains/example",
      "text": "Learn more"
    }
  ],
  "contentType": "text/html; charset=utf-8",
  "bytes": 513,
  "truncated": false,
  "attestation": {
    "keyId": "mercury-x402-attestation-v1:0x<signer>",
    "alg": "EIP-191-personal_sign",
    "address": "0x<signer-from-/.well-known/mercury-attestation>",
    "contentHash": "0xc372f751afc12f338f7b3cc8ce610bc548c40338bb80c8e0e0b0c06c707a146c",
    "nonce": "0x<16-random-bytes>",
    "signedAt": "2026-06-03T00:00:00.000Z",
    "signature": "0x<65-byte EIP-191 signature>",
    "verify": {
      "message": "mercury-x402:fetch-attestation:v1\nurl=https://example.com/\nstatus=200\nsha256=0xc372…\nfetchedAt=2026-06-03T00:00:00.000Z\nnonce=0x…",
      "howTo": "EIP-191 ecrecover this message; signer must equal address. Recompute sha256(text)==contentHash."
    }
  }
}

Price ladder — each tier delivers genuinely more work, never the same bytes at a markup.

TierPriceIncludes
fetch$0.003clean page text + signed provenance receipt
plus$0.006+ markdown structure + outbound-link graph
pro$0.012+ deterministic structured-extract JSON record

Pay & call

Your agent calls the route; the 402 challenge carries the exact price ($0.003, USDC on Base mainnet); the x402 client settles via the CDP facilitator and retries. No key, no signup.

agent.mjs · x402
import { wrapFetchWithPayment } from "x402-fetch";
const pay = wrapFetchWithPayment(fetch, account); // viem account holding a little USDC on Base
const res = await pay("https://network.mercury-hq.com/buy/fetch?url=https://example.com");
const out = await res.json(); // the result + `attestation` (the signed receipt)

Prepaid alternative — the same route accepts an API key:

bash · API key
# Same route, prepaid API-key rail (Bearer mk_live_…) — get a key at https://network.mercury-hq.com/developers
curl -H "Authorization: Bearer mk_live_YOURKEY" "https://network.mercury-hq.com/buy/fetch?url=https://example.com"
Pay over 402 — get the missing pieceEvery paid call returns an EIP-191 signed receipt — verify it free at /x402/verify.

Verify the receipt

Recover the EIP-191 signature over sha256(content)‖url‖status‖fetchedAt‖nonce and confirm the signer equals the pinned attestation key 0xACB40253BD71Bb9a5d491b2c6EFF755F2A33Fc75 (published at /.well-known/mercury-attestation). No callback to Mercury — the receipt verifies offline, forever. Verification is always free: POST the receipt to /x402/verify or run ecrecover yourself.

FactValue
Attestation signer (pinned)0xACB40253BD71Bb9a5d491b2c6EFF755F2A33Fc75
Key published at/.well-known/mercury-attestation
Live verifier (free)/x402/verify
Settlementreal USDC on Base mainnet (eip155:8453) via CDP — auditable on BaseScan
List of URLs (≤20) → clean content for each + ONE signed receipt committing to a MERKLE ROOT over every page's contentHash. Tamper-evident multi-page…
Open
URL → clean, LLM-ready markdown (boilerplate/nav/ads stripped, headings + lists + links preserved) with a signed provenance receipt pinning the…
Open
URL → a clean ARTICLE record { title, byline, publishedAt, article text } with boilerplate (nav/header/footer/sidebar/ads/share-bars/comment-forms)…
Open

More: all services · /catalog · the headline web-fetch · agent twin of this page: GET /university/docs/web-fetch?format=md