---
title: "MERCURY Cited Batch — signed multi-page snapshot (Merkle root over every page's contentHash + per-page proofs)"
method: GET
path: "/buy/batch"
tags: ["cited-batch", "merkle-root", "merkle-proof", "batch-fetch", "multi-url", "snapshot", "tamper-evident", "verifiable-web-fetch", "attestation", "provenance", "verifiable-data-record", "audit-trail", "rag", "agent-web-fetch", "scraping", "keyless", "agent-native"]
---

# MERCURY Cited Batch — signed multi-page snapshot (Merkle root over every page's contentHash + per-page proofs)

`GET /buy/batch`

## Request

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

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 snapshot with per-page membership proofs (selective disclosure). Deterministic (no LLM): same URL set + same source bytes ⇒ byte-identical root + proofs. SSRF-guarded per url; keyless x402, USDC on Base mainnet.

## Query parameters

- `urls` string, required: comma- OR newline-separated list of pages to snapshot (http/https), ≤20 (deduped, capped). Each is fetched through the shared SSRF-guarded engine and becomes one Merkle leaf.
- `format` 'text' | 'markdown': clean text (default) or structure-preserving markdown for every page

## Response `200`

Delivered after the x402 payment settles on Base mainnet.

- object
  - `ok` boolean, required: true on success; false on an honest failure (503-before-charge)
  - `url` string, required: synthetic batch id (mercury-batch:<merkleRoot>) — there is no single url
  - `status` integer: 200 when at least one page resolved (the batch is deliverable)
  - `text` string: the canonical BATCH COMMITMENT string the attestation signs over: the Merkle root + counts + every (index,url,status,contentHash,leafHash). This is the proof, not the page bodies.
  - `fetchedAt` string: ISO-8601 capture time (also folded into the signed receipt)
  - `data` object: the structured deliverable the buyer consumes
    - `merkleRoot` string: 0x… sha256 Merkle root committing to ALL pages at once
    - `leafCount` integer: number of pages that resolved into a leaf (successful fetches)
    - `requested` integer: number of urls accepted into the batch (after dedupe/cap)
    - `okCount` integer: successful fetches (== leafCount)
    - `failCount` integer: fetches that returned an honest ok:false (excluded from the tree)
    - `leafTag` string: domain separator used for leaf hashing (verifier needs it)
    - `nodeTag` string: domain separator used for internal-node hashing (verifier needs it)
    - `pages` object[]: per-page result, in input order. Successful pages carry text + contentHash + a Merkle proof.
      - `index` integer: leaf index in the snapshot (part of the signed leaf)
      - `url` string: final URL after redirects (or the requested url on failure)
      - `ok` boolean
      - `status` integer: upstream HTTP status
      - `title` string: page <title> (HTML pages only)
      - `text` string: cleaned page text/markdown (omitted on failure)
      - `contentHash` string: 0x… sha256 of the page text (the leaf's content commitment)
      - `leafHash` string: 0x… sha256 leaf node = H(leafTag|index|url|status|contentHash)
      - `proof` object[]: Merkle audit path: fold this leafHash with each {side,hash} to recompute merkleRoot. Proves THIS page was a member of the signed batch WITHOUT disclosing the other pages.
        - `side` 'left' | 'right'
        - `hash` string
      - `bytes` integer: raw upstream body size
      - `contentType` string
      - `redirects` string[]
      - `error` string: present only when this page's ok:false
    - `dropped` string[]: urls dropped for exceeding the ≤20 cap (honest: we tell you what we capped)
  - `error` string: present only when ok:false (e.g. no urls supplied, or every page failed)

## 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)
