Mercury · Cited Feed
GET /buy/feed
What it does
RSS/Atom feed URL → a SIGNED, normalized item list [{title,link,published,summary}] unified across RSS 2.0/RDF + Atom 1.0: CDATA unwrapped, HTML stripped, entities decoded, dates → ISO-8601 (publishedRaw kept verbatim, never fabricated). Deterministic — same feed bytes ⇒ byte-identical items; no LLM. Core 4 fields only (not full-content/media/author). Receipt = EIP-191 over the canonical item list.
The goal it serves: turn a page into a typed record an agent can act on, with the signed receipt proving the fields are exactly what Mercury resolved from the source — deterministic, keyless, no LLM.
Schemas & output preview
Input schema — the exact request shape the route validates.
{
"type": "object",
"properties": {
"url": {
"type": "string",
"maxLength": 2048,
"description": "the RSS/Atom feed to normalize (http/https)"
}
},
"required": [
"url"
],
"additionalProperties": false
}Output schema — the exact response shape the handler returns.
{
"type": "object",
"properties": {
"ok": {
"type": "boolean",
"description": "true on success; false on an honest failure (still delivered)"
},
"url": {
"type": "string",
"description": "final feed URL after redirects"
},
"status": {
"type": "integer",
"description": "upstream HTTP status"
},
"data": {
"type": "object",
"description": "the normalized feed (the product the buyer consumes)",
"properties": {
"feedTitle": {
"type": "string",
"description": "channel/feed <title>"
},
"kind": {
"type": "string",
"enum": [
"rss",
"atom"
],
"description": "which dialect was parsed"
},
"count": {
"type": "integer",
"description": "number of normalized items (capped at 100)"
},
"items": {
"type": "array",
"description": "uniform item records across both dialects",
"items": {
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "item/entry title (CDATA-unwrapped, decoded)"
},
"link": {
"type": "string",
"description": "canonical article URL (Atom alternate / RSS link / permalink id)"
},
"published": {
"type": "string",
"description": "ISO-8601 UTC when parseable, else empty (see publishedRaw)"
},
"publishedRaw": {
"type": "string",
"description": "the feed's original date string, verbatim (honest)"
},
"summary": {
"type": "string",
"description": "item description/summary, HTML stripped, ≤1000 chars"
}
}
}
}
}
},
"text": {
"type": "string",
"description": "canonical JSON string the signed receipt covers (data, with object keys sorted)"
},
"contentType": {
"type": "string"
},
"fetchedAt": {
"type": "string",
"description": "ISO8601 fetch time (in the signed payload)"
},
"error": {
"type": "string",
"description": "present only when ok:false"
}
},
"required": [
"ok",
"url"
],
"additionalProperties": false
}Output preview — a real example response, shown free (you only pay when you call the route).
{
"ok": true,
"url": "https://blog.rust-lang.org/feed.xml",
"status": 200,
"data": {
"feedTitle": "The Rust Programming Language Blog",
"kind": "atom",
"count": 1,
"items": [
{
"title": "Launching the Rust Foundation Maintainers Fund",
"link": "https://blog.rust-lang.org/2026/06/02/launching-the-rust-foundation-maintainers-fund/",
"published": "2026-06-02T00:00:00.000Z",
"publishedRaw": "2026-06-02T00:00:00+00:00",
"summary": "The Rust Foundation announces a new fund supporting project maintainers."
}
]
},
"text": "{\"count\":1,\"feedTitle\":\"The Rust Programming Language Blog\",\"items\":[{\"link\":\"https://blog.rust-lang.org/2026/06/02/launching-the-rust-foundation-maintainers-fund/\",\"published\":\"2026-06-02T00:00:00.000Z\",\"publishedRaw\":\"2026-06-02T00:00:00+00:00\",\"summary\":\"The Rust Foundation announces a new fund supporting project maintainers.\",\"title\":\"Launching the Rust Foundation Maintainers Fund\"}],\"kind\":\"atom\"}",
"contentType": "application/xml",
"fetchedAt": "2026-06-04T00:00:00.000Z"
}Pay & call
Your agent calls the route; the 402 challenge carries the exact price ($0.005, USDC on Base mainnet); the x402 client settles via the CDP facilitator and retries. No key, no signup.
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/feed?url=https://example.com");
const out = await res.json(); // the result + `attestation` (the signed receipt)Prepaid alternative — the same route accepts an 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/feed?url=https://example.com"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.
| Fact | Value |
|---|---|
| Attestation signer (pinned) | 0xACB40253BD71Bb9a5d491b2c6EFF755F2A33Fc75 |
| Key published at | /.well-known/mercury-attestation |
| Live verifier (free) | /x402/verify |
| Settlement | real USDC on Base mainnet (eip155:8453) via CDP — auditable on BaseScan |
Related
Cited Links
$0.005Cited Metadata
$0.006Cited Table
$0.006Structured Extract
$0.004More: all services · /catalog · the headline web-fetch · agent twin of this page: GET /university/docs/cited-feed?format=md