openapi: 3.1.0
info:
title: MERCURY x402 storefront
version: '1'
x-spec: mercury-storefront/1
description: Agent-payable resources over HTTP 402 (x402). LIVE — Base mainnet, real USDC, no token. Only currently-deliverable routes are listed (web-fetch is the live paid SKU; mints are gated off). Free discovery at /.well-known/x402, /x402/discovery, /catalog, and /manifest.
servers:
- url: https://network.mercury-hq.com
paths:
/buy/signal:
get:
summary: signal
description: MERCURY Signals — free DEMO/sample read (sample data, not a live market read yet).
operationId: buy_signal
tags:
- data
responses:
'200':
description: Free demo/sample data — no payment.
security: []
/buy/fetch:
get:
summary: MERCURY Verifiable Web Fetch
description: '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.'
operationId: buy_web_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
responses:
'200':
description: Delivered after the x402 payment settles on Base mainnet.
content:
application/json:
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
(s) parsed into typed, header-keyed rows (JSON) + clean RFC-4180 CSV, with a signed provenance receipt over the exact extracted grid. Deterministic, keyless, no LLM — x402, USDC on Base mainnet.
operationId: buy_cited_table
tags:
- html-table-extraction
- table-to-json
- table-to-csv
- url-to-table
- structured-data-extraction
- web-scraping-api
- data-extraction-api
- data-aggregation
- llm-ready-data
- verifiable-extract
- attestation
- provenance
- keyless
- agent-native
- rag
responses:
'200':
description: Delivered after the x402 payment settles on Base mainnet.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
description: true on success; false on an honest failure (still delivered, but 503-before-charge)
url:
type: string
description: final URL after redirects
status:
type: integer
description: upstream HTTP status
text:
type: string
description: 'the canonical signed string: JSON.stringify(data, sorted-keys) — the exact bytes the provenance receipt covers'
fetchedAt:
type: string
description: ISO timestamp of the fetch (also in the signed attestation)
data:
type: object
description: the structured product the buyer consumes
properties:
title:
type: string
description: page
tableCount:
type: integer
description: number of data tables found on the page
returned:
type: integer
description: number of tables returned in this response
truncatedTables:
type: boolean
description: true if MAX_TABLES clipped the set
tables:
type: array
description: each extracted table
items:
type: object
properties:
index:
type: integer
description: 0-based position in the document
columns:
type: array
items:
type: string
description: ordered, de-duplicated column names (from
/first row)
rowCount:
type: integer
ragged:
type: boolean
description: true if any row's cell count != header width (colspan/rowspan)
rows:
type: array
description: header-keyed row objects (cell text)
items:
type: object
additionalProperties:
type: string
csv:
type: string
description: RFC-4180 CSV of this table (omitted when ?format=json)
attestation:
type: object
description: EIP-191 provenance receipt over `text` (the canonical sorted-key JSON of the extracted grid), ecrecoverable OFFLINE (key at /.well-known/mercury-attestation). Proves the ROWS are genuine + untampered.
properties:
keyId:
type: string
alg:
type: string
address:
type: string
contentHash:
type: string
nonce:
type: string
signedAt:
type: string
signature:
type: string
verify:
type: object
properties:
message:
type: string
howTo:
type: string
error:
type: string
description: present only when ok:false
required:
- ok
- url
additionalProperties: true
'402':
description: Payment Required — retry with an x402-signed payment (e.g. x402-fetch). Terms are in the challenge body (x402 v1).
parameters:
- name: url
in: query
required: true
schema:
type: string
maxLength: 2048
description: the page to extract tables from (http/https)
description: the page to extract tables from (http/https)
- name: table
in: query
required: false
schema:
type: string
maxLength: 8
description: 'optional: 0-based index of a SINGLE table to return (document order). Omit to return ALL tables found (up to the cap).'
description: 'optional: 0-based index of a SINGLE table to return (document order). Omit to return ALL tables found (up to the cap).'
- name: format
in: query
required: false
schema:
type: string
enum:
- both
- json
- csv
description: 'optional: which serialisations to include in `data` (default: both).'
description: 'optional: which serialisations to include in `data` (default: both).'
x-payment-info:
protocols:
- x402
scheme: exact
price: $0.006
currency: USDC
network: base
networkCaip2: eip155:8453
testnet: false
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
x402Version: 1
x-x402:
scheme: exact
price: $0.006
currency: USDC
network: base
networkCaip2: eip155:8453
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
testnet: false
maxTimeoutSeconds: 60
/buy/feed:
get:
summary: MERCURY Cited Feed
description: '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.'
operationId: buy_cited_feed
tags:
- cited-feed
- rss
- atom
- feed-parser
- news-feed
- rss-to-json
- feed-normalization
- verifiable-data-record
- attestation
- provenance
- keyless
- agent-native
- rag
- news-agents
- data-feed
responses:
'200':
description: Delivered after the x402 payment settles on Base mainnet.
content:
application/json:
schema:
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
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
'402':
description: Payment Required — retry with an x402-signed payment (e.g. x402-fetch). Terms are in the challenge body (x402 v1).
parameters:
- name: url
in: query
required: true
schema:
type: string
maxLength: 2048
description: the RSS/Atom feed to normalize (http/https)
description: the RSS/Atom feed to normalize (http/https)
x-payment-info:
protocols:
- x402
scheme: exact
price: $0.005
currency: USDC
network: base
networkCaip2: eip155:8453
testnet: false
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
x402Version: 1
x-x402:
scheme: exact
price: $0.005
currency: USDC
network: base
networkCaip2: eip155:8453
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
testnet: false
maxTimeoutSeconds: 60
/buy/availability:
get:
summary: MERCURY Cited Availability Probe
description: 'URL → a signed uptime/status probe: up/down, HTTP status + class, reachability reason, final URL after redirects, and a measured responseMs — wrapped in an offline-verifiable provenance receipt that makes "it was up/down at T" provable SLA evidence. Deterministic verdict (responseMs is telemetry, not signed). Keyless, no LLM, no signup.'
operationId: buy_cited_availability
tags:
- cited-availability
- uptime
- uptime-monitoring
- status-probe
- availability
- sla
- sla-evidence
- health-check
- vendor-risk
- incident-timeline
- attestation
- provenance
- verifiable-data-record
- agent-native
- keyless
- data-feed
responses:
'200':
description: Delivered after the x402 payment settles on Base mainnet.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
description: true once the PROBE completed (the host was reached at the network/HTTP layer); false only when the probe itself could not be performed against a reachable host
url:
type: string
description: final URL after redirects (or the requested URL when unreachable)
status:
type:
- integer
- 'null'
description: upstream HTTP status observed (null when the host never responded)
text:
type: string
description: canonical sorted-key JSON of the signed verdict — the exact string the receipt signs over (responseMs deliberately excluded for determinism)
fetchedAt:
type: string
description: ISO-8601 probe time (provenance metadata bound by the receipt)
data:
type: object
description: the deterministic availability verdict
properties:
up:
type: boolean
description: true iff the host responded with a non-error class (2xx/3xx)
reachable:
type: boolean
description: true iff the host produced ANY HTTP response (a 4xx/5xx host is reachable but not up)
httpStatus:
type:
- integer
- 'null'
description: the observed HTTP status, or null when unreachable
responseClass:
type: string
enum:
- 1xx-informational
- 2xx-success
- 3xx-redirect
- 4xx-client-error
- 5xx-server-error
- unknown
- none
reason:
type: string
description: 'stable reachability category: ok | | dns-failure | timeout | connection-refused | connection-reset | tls-error | redirect-loop | blocked-ssrf | invalid-url | unreachable'
responseMs:
type:
- integer
- 'null'
description: measured round-trip ms (TELEMETRY — NOT part of the signed text; non-deterministic by nature)
rubric:
type: string
description: verdict rubric version id
required:
- up
- reachable
- httpStatus
- responseClass
- reason
- rubric
additionalProperties: false
attestation:
type: object
description: EIP-191 provenance receipt over the canonical verdict text — verifiable OFFLINE by anyone (key pinned at /.well-known/mercury-attestation). Proves MERCURY observed THIS up/down + status at THIS time. The SLA-evidence wedge a free uptime checker structurally cannot emit.
error:
type: string
description: present only when ok:false (the probe could not be performed)
required:
- ok
- url
additionalProperties: true
'402':
description: Payment Required — retry with an x402-signed payment (e.g. x402-fetch). Terms are in the challenge body (x402 v1).
parameters:
- name: url
in: query
required: true
schema:
type: string
maxLength: 2048
description: the endpoint/page to probe for availability (http/https)
description: the endpoint/page to probe for availability (http/https)
x-payment-info:
protocols:
- x402
scheme: exact
price: $0.005
currency: USDC
network: base
networkCaip2: eip155:8453
testnet: false
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
x402Version: 1
x-x402:
scheme: exact
price: $0.005
currency: USDC
network: base
networkCaip2: eip155:8453
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
testnet: false
maxTimeoutSeconds: 60
/buy/validate:
get:
summary: Cited Validate — JSON API response vs JSON Schema, signed pass/fail + per-field errors (keyless x402)
description: URL (a JSON/API endpoint) + a JSON Schema in → a deterministic pass/fail with per-field errors (missing/wrong-type/enum/range/pattern), plus a signed provenance receipt binding the verdict to the exact response bytes AND the exact schema. Deterministic, keyless, no LLM — x402, USDC on Base mainnet.
operationId: buy_cited_validate
tags:
- json-schema-validation
- api-response-validation
- schema-validate
- contract-testing
- data-validation-api
- url-to-validation
- json-validator
- verifiable-validation
- attestation
- provenance
- keyless
- agent-native
- data-quality
responses:
'200':
description: Delivered after the x402 payment settles on Base mainnet.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
description: true when the validation RAN (delivered); false on an honest undeliverable (503-before-charge)
url:
type: string
description: final URL after redirects
status:
type: integer
description: upstream HTTP status of the fetched JSON
text:
type: string
description: 'the canonical signed string: JSON.stringify(report, sorted-keys) — the exact bytes the provenance receipt covers (embeds documentHash + schemaHash + verdict)'
fetchedAt:
type: string
description: ISO timestamp of the fetch (also in the signed attestation)
data:
type: object
description: the validation report the buyer consumes
properties:
valid:
type: boolean
description: true iff the fetched JSON conforms to the schema with zero errors
errorCount:
type: integer
description: number of validation errors found
errors:
type: array
description: per-field errors in document order (empty when valid)
items:
type: object
properties:
path:
type: string
description: JSON-Pointer path to the offending value
keyword:
type: string
description: the schema keyword that failed (type, required, enum, minimum, pattern, …)
message:
type: string
description: human-readable reason
truncated:
type: boolean
description: true if the error cap clipped the list (still honest about more existing)
documentHash:
type: string
description: 0x… sha256 of the canonical JSON document that was validated
schemaHash:
type: string
description: 0x… sha256 of the canonical (normalised) schema that was applied
schemaForm:
type: string
description: 'which input form was used: compact | json-schema | shorthand'
pointer:
type: string
description: the JSON-Pointer applied (empty for whole-body validation)
validatedType:
type: string
description: the JSON type of the validated (sub-)document
attestation:
type: object
description: 'EIP-191 provenance receipt over `text` (the canonical sorted-key JSON of the report, which embeds documentHash + schemaHash + verdict), ecrecoverable OFFLINE (key at /.well-known/mercury-attestation). Proves: which schema was checked, which bytes were checked, and the verdict — all at fetchedAt.'
properties:
keyId:
type: string
alg:
type: string
address:
type: string
contentHash:
type: string
nonce:
type: string
signedAt:
type: string
signature:
type: string
verify:
type: object
properties:
message:
type: string
howTo:
type: string
error:
type: string
description: present only when ok:false (undeliverable, not charged)
required:
- ok
- url
additionalProperties: true
'402':
description: Payment Required — retry with an x402-signed payment (e.g. x402-fetch). Terms are in the challenge body (x402 v1).
parameters:
- name: url
in: query
required: true
schema:
type: string
maxLength: 2048
description: the JSON/API endpoint to fetch + validate (http/https)
description: the JSON/API endpoint to fetch + validate (http/https)
- name: schema
in: query
required: true
schema:
type: string
maxLength: 16384
description: 'the JSON Schema to validate against. THREE accepted forms: (1) COMPACT URL-native comma list of field[:type] (type in string|number|integer|boolean|array|object|null; default string), e.g. id:integer,name,price:number,inStock:boolean — every field becomes a REQUIRED typed property; (2) a JSON-Schema string (Draft-07 core subset: type/required/properties/items/enum/const/min*/max*/pattern/format/additionalProperties/nullable/anyOf/oneOf/allOf/not); (3) a shorthand-map string {"id":"integer","name":"string"}.'
description: 'the JSON Schema to validate against. THREE accepted forms: (1) COMPACT URL-native comma list of field[:type] (type in string|number|integer|boolean|array|object|null; default string), e.g. id:integer,name,price:number,inStock:boolean — every field becomes a REQUIRED typed property; (2) a JSON-Schema string (Draft-07 core subset: type/required/properties/items/enum/const/min*/max*/pattern/format/additionalProperties/nullable/anyOf/oneOf/allOf/not); (3) a shorthand-map string {"id":"integer","name":"string"}.'
- name: pointer
in: query
required: false
schema:
type: string
maxLength: 256
description: optional JSON-Pointer (e.g. /data or /result/0) to validate a SUB-DOCUMENT of the response instead of the whole body (for APIs that wrap the payload).
description: optional JSON-Pointer (e.g. /data or /result/0) to validate a SUB-DOCUMENT of the response instead of the whole body (for APIs that wrap the payload).
x-payment-info:
protocols:
- x402
scheme: exact
price: $0.005
currency: USDC
network: base
networkCaip2: eip155:8453
testnet: false
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
x402Version: 1
x-x402:
scheme: exact
price: $0.005
currency: USDC
network: base
networkCaip2: eip155:8453
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
testnet: false
maxTimeoutSeconds: 60
/buy/batch:
get:
summary: MERCURY Cited Batch — signed multi-page snapshot (Merkle root over every page's contentHash + per-page proofs)
description: '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.'
operationId: buy_cited_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
responses:
'200':
description: Delivered after the x402 payment settles on Base mainnet.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
description: true on success; false on an honest failure (503-before-charge)
url:
type: string
description: synthetic batch id (mercury-batch:) — there is no single url
status:
type: integer
description: 200 when at least one page resolved (the batch is deliverable)
text:
type: string
description: '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:
type: string
description: ISO-8601 capture time (also folded into the signed receipt)
data:
type: object
description: the structured deliverable the buyer consumes
properties:
merkleRoot:
type: string
description: 0x… sha256 Merkle root committing to ALL pages at once
leafCount:
type: integer
description: number of pages that resolved into a leaf (successful fetches)
requested:
type: integer
description: number of urls accepted into the batch (after dedupe/cap)
okCount:
type: integer
description: successful fetches (== leafCount)
failCount:
type: integer
description: fetches that returned an honest ok:false (excluded from the tree)
leafTag:
type: string
description: domain separator used for leaf hashing (verifier needs it)
nodeTag:
type: string
description: domain separator used for internal-node hashing (verifier needs it)
pages:
type: array
description: per-page result, in input order. Successful pages carry text + contentHash + a Merkle proof.
items:
type: object
properties:
index:
type: integer
description: leaf index in the snapshot (part of the signed leaf)
url:
type: string
description: final URL after redirects (or the requested url on failure)
ok:
type: boolean
status:
type: integer
description: upstream HTTP status
title:
type: string
description: page (HTML pages only)
text:
type: string
description: cleaned page text/markdown (omitted on failure)
contentHash:
type: string
description: 0x… sha256 of the page text (the leaf's content commitment)
leafHash:
type: string
description: 0x… sha256 leaf node = H(leafTag|index|url|status|contentHash)
proof:
type: array
description: '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.'
items:
type: object
properties:
side:
type: string
enum:
- left
- right
hash:
type: string
bytes:
type: integer
description: raw upstream body size
contentType:
type: string
redirects:
type: array
items:
type: string
error:
type: string
description: present only when this page's ok:false
dropped:
type: array
items:
type: string
description: 'urls dropped for exceeding the ≤20 cap (honest: we tell you what we capped)'
additionalProperties: false
error:
type: string
description: present only when ok:false (e.g. no urls supplied, or every page failed)
required:
- ok
- url
additionalProperties: false
'402':
description: Payment Required — retry with an x402-signed payment (e.g. x402-fetch). Terms are in the challenge body (x402 v1).
parameters:
- name: urls
in: query
required: true
schema:
type: string
maxLength: 65536
description: 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.
description: 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.
- name: format
in: query
required: false
schema:
type: string
enum:
- text
- markdown
description: clean text (default) or structure-preserving markdown for every page
description: clean text (default) or structure-preserving markdown for every page
x-payment-info:
protocols:
- x402
scheme: exact
price: $0.02
currency: USDC
network: base
networkCaip2: eip155:8453
testnet: false
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
x402Version: 1
x-x402:
scheme: exact
price: $0.02
currency: USDC
network: base
networkCaip2: eip155:8453
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
testnet: false
maxTimeoutSeconds: 60
/buy/sitemap:
get:
summary: MERCURY Cited Sitemap
description: 'Domain/URL → a SIGNED snapshot of the site''s PUBLISHED sitemap: discovers the sitemap via robots.txt Sitemap: lines then /sitemap.xml fallback, parses + (follows up to 5 child sitemaps), returns a deduped, bounded (≤2000) URL inventory with lastmod/changefreq/priority. The receipt signs the DECLARED URL list (deterministic — same sitemap bytes ⇒ byte-identical list). Optional ?fetch=N (≤10) adds a HARD-BOUNDED same-domain liveness probe (title+status+bytes per URL) — that probe is the ONLY non-deterministic part and is NOT covered by the signature. SSRF-guarded; the crawl is bounded at every axis.'
operationId: buy_cited_sitemap
tags:
- cited-sitemap
- sitemap
- sitemap-xml
- crawl-frontier
- url-inventory
- seo
- indexability
- site-coverage
- verifiable-data-record
- attestation
- provenance
- keyless
- agent-native
- scraping
- rag
responses:
'200':
description: Delivered after the x402 payment settles on Base mainnet.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
description: true on success; false on an honest failure (still delivered)
url:
type: string
description: the sitemap URL that was fetched + parsed
status:
type: integer
description: upstream HTTP status of the sitemap fetch
data:
type: object
description: the structured sitemap snapshot (the product the buyer consumes)
properties:
origin:
type: string
description: scheme://host the sitemap was discovered for
sitemapUrl:
type: string
description: the sitemap that was parsed
discoveredVia:
type: string
enum:
- robots.txt
- sitemap.xml
- input
description: 'how the sitemap was located (robots Sitemap: line / conventional path / direct input)'
robotsSitemaps:
type: array
description: 'all Sitemap: URLs robots.txt declared (may be > the one parsed)'
items:
type: string
kind:
type: string
enum:
- urlset
- sitemapindex
- unknown
description: which sitemap schema was parsed
childSitemaps:
type: array
description: child sitemaps followed from a (bounded to 5)
items:
type: string
total:
type: integer
description: number of unique page URLs returned
truncated:
type: boolean
description: true if the site declared more URLs than the 2000 cap / requested limit
urls:
type: array
description: the published URL inventory (deduped, origin-then-loc sorted)
items:
type: object
properties:
loc:
type: string
description: absolute page URL
lastmod:
type: string
description: declared last-modified (only if present)
changefreq:
type: string
description: declared change frequency (only if present)
priority:
type: string
description: declared crawl priority (only if present)
probe:
type: array
description: 'OPTIONAL liveness sample (?fetch=N): first N same-domain URLs shallow-fetched. NOT covered by the signed receipt — live status can change between calls.'
items:
type: object
properties:
url:
type: string
ok:
type: boolean
status:
type: integer
title:
type: string
bytes:
type: integer
error:
type: string
description: present only when that URL failed
text:
type: string
description: 'canonical newline string the signed receipt covers: one URL per line, origin-then-loc sorted (the DECLARED inventory only — never the live-probe sample, so it is reproducible)'
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
'402':
description: Payment Required — retry with an x402-signed payment (e.g. x402-fetch). Terms are in the challenge body (x402 v1).
parameters:
- name: url
in: query
required: true
schema:
type: string
maxLength: 2048
description: a domain (example.com) or any URL on the site — only its origin is used
description: a domain (example.com) or any URL on the site — only its origin is used
- name: fetch
in: query
required: false
schema:
type: string
maxLength: 3
description: 'optional N (0–10): also shallow-fetch the first N same-domain sitemap URLs and report each one''s live title + HTTP status + byte size (liveness sample). NOT covered by the signed receipt (it can change between calls). Default 0 = off.'
description: 'optional N (0–10): also shallow-fetch the first N same-domain sitemap URLs and report each one''s live title + HTTP status + byte size (liveness sample). NOT covered by the signed receipt (it can change between calls). Default 0 = off.'
- name: limit
in: query
required: false
schema:
type: string
maxLength: 4
description: optional cap on URLs returned (1–2000); default returns all up to 2000
description: optional cap on URLs returned (1–2000); default returns all up to 2000
x-payment-info:
protocols:
- x402
scheme: exact
price: $0.01
currency: USDC
network: base
networkCaip2: eip155:8453
testnet: false
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
x402Version: 1
x-x402:
scheme: exact
price: $0.01
currency: USDC
network: base
networkCaip2: eip155:8453
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
testnet: false
maxTimeoutSeconds: 60
/buy/dns:
get:
summary: MERCURY Cited DNS Snapshot
description: Domain → a SIGNED, timestamped DNS snapshot (A, AAAA, MX, NS, TXT, CNAME, SOA), normalised + sorted into a byte-stable record set with an offline-verifiable provenance receipt — proving exactly what the zone resolved to at that moment. Keyless, no LLM, no signup. (Normalisation is deterministic; DNS itself is mutable across time/TTL/geo — which is the very reason the snapshot is timestamped + signed.)
operationId: buy_cited_dns
tags:
- cited-dns
- dns
- dns-records
- dns-snapshot
- mx-records
- spf
- dmarc
- nameservers
- domain-audit
- dns-hijack-evidence
- vendor-risk
- attestation
- provenance
- verifiable-data-record
- agent-native
- keyless
- data-feed
responses:
'200':
description: Delivered after the x402 payment settles on Base mainnet.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
description: true on success; false on an honest failure (never charged for a stub)
url:
type: string
description: the resolved domain (echoed in the `url` field for gate uniformity)
domain:
type: string
description: the normalised, lower-cased, trailing-dot-stripped domain that was resolved
status:
type: integer
description: 200 on a successful resolve (HTTP-shaped status for gate uniformity)
text:
type: string
description: canonical sorted-key JSON of `data` — the exact string the receipt signs over
resolvedAt:
type: string
description: ISO-8601 resolve time (provenance metadata; binds WHEN the snapshot was taken)
fetchedAt:
type: string
description: alias of resolvedAt for gate/receipt uniformity
data:
type: object
description: the deterministic, normalised DNS snapshot
properties:
domain:
type: string
resolver:
description: pinned resolver IPs used, or 'system'
type:
- array
- string
items:
type: string
records:
type: object
description: normalised record sets keyed by type (A, AAAA, MX, NS, TXT, CNAME, SOA); sorted + de-duplicated
properties:
A:
type: array
items:
type: string
AAAA:
type: array
items:
type: string
MX:
type: array
items:
type: object
properties:
priority:
type: integer
exchange:
type: string
NS:
type: array
items:
type: string
TXT:
type: array
items:
type: string
CNAME:
type: array
items:
type: string
SOA:
type:
- object
- 'null'
properties:
nsname:
type: string
hostmaster:
type: string
serial:
type: integer
refresh:
type: integer
retry:
type: integer
expire:
type: integer
minttl:
type: integer
summary:
type: object
description: record counts per type (derived, deterministic)
flags:
type: object
description: derived convenience flags (hasSpf, hasDmarc) pointing into TXT
partialErrors:
type: object
description: present only if a record type had a transport error; never fabricated data
snapshot:
type: string
description: 'rubric/version tag: mercury-cited-dns-v1'
error:
type: string
description: present only when ok:false
required:
- ok
- url
additionalProperties: true
'402':
description: Payment Required — retry with an x402-signed payment (e.g. x402-fetch). Terms are in the challenge body (x402 v1).
parameters:
- name: domain
in: query
required: false
schema:
type: string
maxLength: 253
description: the domain to resolve (e.g. example.com). A full URL is also accepted; its hostname is used.
description: the domain to resolve (e.g. example.com). A full URL is also accepted; its hostname is used.
- name: url
in: query
required: false
schema:
type: string
maxLength: 2048
description: alternative to ?domain= — any http/https URL; the registrable hostname is resolved.
description: alternative to ?domain= — any http/https URL; the registrable hostname is resolved.
x-payment-info:
protocols:
- x402
scheme: exact
price: $0.006
currency: USDC
network: base
networkCaip2: eip155:8453
testnet: false
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
x402Version: 1
x-x402:
scheme: exact
price: $0.006
currency: USDC
network: base
networkCaip2: eip155:8453
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
testnet: false
maxTimeoutSeconds: 60
/buy/readability:
get:
summary: MERCURY Cited Readability
description: 'URL → a clean ARTICLE record { title, byline, publishedAt, article text } with boilerplate (nav/header/footer/sidebar/ads/share-bars/comment-forms) stripped via deterministic DOM density heuristics, plus a signed provenance receipt pinning the cleaned article to its source — the clean-citation primitive distinct from raw markdown. Deterministic (no LLM): same URL + same source bytes ⇒ byte-identical output.'
operationId: buy_cited_readability
tags:
- cited-readability
- readability
- article-extraction
- boilerplate-removal
- clean-citation
- rag
- rag-ingest
- verifiable-web-fetch
- attestation
- provenance
- verifiable-data-record
- llm-ready
- agent-web-fetch
- scraping
- keyless
- agent-native
responses:
'200':
description: Delivered after the x402 payment settles on Base mainnet.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
description: true on success; false on an honest failure (503-before-charge — you are NOT billed)
url:
type: string
description: final URL after redirects
status:
type: integer
description: upstream HTTP status
text:
type: string
description: 'the canonical signed string: JSON.stringify(data, sortedKeys). The EIP-191 attestation signs THIS, so the buyer can prove the WHOLE article record (title+byline+date+body) is exactly what MERCURY extracted from this url at this time.'
fetchedAt:
type: string
description: ISO-8601 fetch time (also folded into the signed receipt)
data:
type: object
description: the structured article record the buyer consumes
properties:
title:
type:
- string
- 'null'
description: article headline (JSON-LD headline/name → og:title → )
byline:
type:
- string
- 'null'
description: author/byline (JSON-LD author → article:author/author meta), 'By ' prefix stripped
publishedAt:
type:
- string
- 'null'
description: publish date, ISO-8601 when parseable (JSON-LD datePublished → article:published_time); raw string if present but un-parseable; null if absent
siteName:
type:
- string
- 'null'
description: publication / site name (og:site_name) when present
excerpt:
type:
- string
- 'null'
description: page description (meta/og) or the first ~280 chars of the body — a citation card
articleText:
type: string
description: the cleaned article body prose, boilerplate stripped
wordCount:
type: integer
description: word count of the cleaned article body (for chunk/cost budgeting)
extractedBy:
type: string
enum:
- landmark
- density
- fallback
description: which deterministic strategy isolated the body (article/main landmark, density scorer, or whole-body fallback)
contentType:
type: string
bytes:
type: integer
description: raw upstream body size
truncated:
type: boolean
description: true if the cleaned article hit the text cap
redirects:
type: array
items:
type: string
description: redirect chain followed
additionalProperties: false
error:
type: string
description: present only when ok:false
attestation:
type: object
description: EIP-191 provenance receipt over sha256(text)+url+status+time, verifiable OFFLINE by anyone (key pinned at /.well-known/mercury-attestation). Proves THIS article record is exactly what MERCURY extracted from THIS url at THIS time — the wedge a free reader cannot emit.
required:
- ok
- url
additionalProperties: false
'402':
description: Payment Required — retry with an x402-signed payment (e.g. x402-fetch). Terms are in the challenge body (x402 v1).
parameters:
- name: url
in: query
required: true
schema:
type: string
maxLength: 2048
description: the article page to extract (http/https)
description: the article page to extract (http/https)
x-payment-info:
protocols:
- x402
scheme: exact
price: $0.005
currency: USDC
network: base
networkCaip2: eip155:8453
testnet: false
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
x402Version: 1
x-x402:
scheme: exact
price: $0.005
currency: USDC
network: base
networkCaip2: eip155:8453
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
testnet: false
maxTimeoutSeconds: 60
/buy/redirect:
get:
summary: MERCURY Cited Redirect
description: 'URL → a SIGNED redirect/canonical resolution: the full hop chain [{url,status}] from the link you have to where it ACTUALLY lands, the final resolved URL + status, the page''s , hop count, cross-origin flag and distinct origins traversed (affiliate-cloak / link-safety signal). Deterministic — same redirects ⇒ byte-identical resolution; no LLM. Follows HTTP 3xx only (no JS/meta-refresh execution — meta-refresh target surfaced un-followed). Receipt = EIP-191 over the resolved chain.'
operationId: buy_cited_redirect
tags:
- cited-redirect
- redirect-resolution
- unshorten
- shortlink-expander
- link-safety
- affiliate-cloak-detection
- url-canonical
- destination-provenance
- phishing-check
- verifiable-data-record
- attestation
- provenance
- keyless
- agent-native
- scraping
responses:
'200':
description: Delivered after the x402 payment settles on Base mainnet.
content:
application/json:
schema:
type: object
properties:
ok:
type: boolean
description: true on success; false on an honest failure (still delivered)
url:
type: string
description: final resolved URL after following all HTTP 3xx redirects
status:
type: integer
description: upstream HTTP status of the FINAL resolved URL
data:
type: object
description: the structured redirect/canonical resolution (the product the buyer consumes)
properties:
requestedUrl:
type: string
description: the URL the buyer asked us to resolve
finalUrl:
type: string
description: the destination after all redirects (where the link ACTUALLY goes)
finalStatus:
type: integer
description: upstream HTTP status of the final URL
finalOrigin:
type: string
description: scheme://host of the final URL
canonical:
type:
- string
- 'null'
description: the final page's href, or null
metaRefresh:
type:
- string
- 'null'
description: an UN-followed target on the final page (JS/meta hops are not executed), or null
hopCount:
type: integer
description: number of redirect hops followed (0 = no redirect, direct hit)
redirected:
type: boolean
description: true if the requested URL was redirected at least once
crossOrigin:
type: boolean
description: true if the final origin differs from the requested origin (cloak/affiliate signal)
distinctOrigins:
type: array
description: ordered, de-duplicated origins traversed from requested → final (how many hosts a single click routes through)
items:
type: string
hops:
type: array
description: 'the full hop chain: each step''s URL, its origin, and its HTTP status (null on an intermediate hop whose exact 3xx code the engine did not capture)'
items:
type: object
properties:
url:
type: string
origin:
type: string
description: scheme://host of this hop
status:
type:
- integer
- 'null'
description: HTTP status (final hop = real status; intermediate = null when uncaptured)
redirect:
type: boolean
description: true for an intermediate redirect step, false for the final destination
text:
type: string
description: 'canonical newline string the signed receipt covers (one row per hop: `\t`, requested→final order; trailing `canonical\t`)'
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
'402':
description: Payment Required — retry with an x402-signed payment (e.g. x402-fetch). Terms are in the challenge body (x402 v1).
parameters:
- name: url
in: query
required: true
schema:
type: string
maxLength: 2048
description: the link/URL to resolve (http/https) — e.g. a shortlink or affiliate URL
description: the link/URL to resolve (http/https) — e.g. a shortlink or affiliate URL
x-payment-info:
protocols:
- x402
scheme: exact
price: $0.005
currency: USDC
network: base
networkCaip2: eip155:8453
testnet: false
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
x402Version: 1
x-x402:
scheme: exact
price: $0.005
currency: USDC
network: base
networkCaip2: eip155:8453
asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
testnet: false
maxTimeoutSeconds: 60
x-payment-info:
protocols:
- x402
network: base
currency: USDC
payTo: '0xe10B9d44e72A29B9c19da02981FFCd875308e3C1'
facilitator: https://api.cdp.coinbase.com/platform/v2/x402
testnet: false
spec: mercury-storefront/1