{"name":"url2md","version":"1.4.0","description":"PDFs, JavaScript-rendered pages and ordinary HTML, returned as clean Markdown. Follows robots.txt per RFC 9309.","openapi":"https://url2md.io/openapi.json","contact":{"email":"hello@url2md.io"},"endpoints":{"convert":{"GET":"https://url2md.io/v1/md?url=https://example.com","POST":"https://url2md.io/v1/md with JSON body {\"url\": \"https://example.com\", \"render\": \"auto\", \"format\": \"json\"}","parameters":{"url":"required. An absolute http(s) URL, percent-encoded in the query string","render":"auto (default) | static | browser","format":"json (default) | markdown. Or send Accept: text/markdown"},"headers":"header names are case-insensitive (HTTP/2 delivers payment-required, payment-response and x-url2md-* in lower case)"},"health":"https://url2md.io/health"},"example":{"terms":"curl -i 'https://url2md.io/v1/md?url=https://example.com'","termsReturns":"402 with the terms in the PAYMENT-REQUIRED header (base64 JSON) and a JSON body restating them. Nothing is charged. This is how you read the price before paying it.","paid":"curl -i -H 'PAYMENT-SIGNATURE: <base64 payload>' -H 'Accept: text/markdown' 'https://url2md.io/v1/md?url=https://example.com'","paidNote":"200 with the Markdown, and your settlement receipt in PAYMENT-RESPONSE. The payload is a signed EIP-3009 authorization for the amount in the terms. curl can't produce one, so build it with @x402/fetch (JavaScript) or x402 (Python), which do both calls for you. See pricing.howToPay."},"clients":{"mcp":{"local":{"package":"@url2md-io/mcp","transport":"stdio (local)","tool":"fetch_markdown","docs":"https://www.npmjs.com/package/@url2md-io/mcp","maxPriceUsdDefault":"0.10","how":"Point your MCP client at `npx -y @url2md-io/mcp` with URL2MD_PRIVATE_KEY_FILE naming a file that holds a wallet key with USDC on Base (or URL2MD_PRIVATE_KEY holding the key itself). The server signs each payment with that key, and the key never leaves your machine. Mind the scope: the unscoped `url2md-mcp` on npm is an unrelated publisher's package.","config":{"mcpServers":{"url2md":{"command":"npx","args":["-y","@url2md-io/mcp"],"env":{"URL2MD_PRIVATE_KEY_FILE":"/Users/you/.url2md-key","URL2MD_BASE_URL":"https://url2md.io"}}}}},"remote":{"transport":"Streamable HTTP (hosted)","path":"/mcp","tool":"fetch_markdown","auth":"OAuth 2.1 with PKCE (S256) and a GitHub sign-in, with dynamic client registration or a client ID metadata document","tolls":"never paid here. A page that charges an x402 toll comes back as a tool error naming the paid HTTP endpoint and the local server, which do pay","howToAdd":"In claude.ai: Customize → Connectors → Add custom connector → paste the URL → Add → Connect → sign in with GitHub.","url":"https://url2md.io/mcp","allowance":{"callsPerWindow":100,"browserRendersPerWindow":20,"windowDays":30,"dailyCallsAllUsers":2000}}}},"pricing":{"model":"x402","protocolVersion":2,"price":"$0.005","priceAtomic":"5000","asset":"USDC","assetAddress":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","network":"eip155:8453","chain":"Base","payTo":"0xa09aE66Ec8664475697FfC0eb45aa3Fe52Aa6030","facilitator":"https://api.cdp.coinbase.com/platform/v2/x402","paidRoutes":["GET /v1/md","POST /v1/md"],"freeRoutes":["GET /","GET /.well-known/x402","GET /health","GET /openapi.json","GET /icon.svg","GET /icon.png","GET /favicon.svg","GET /og.png","GET /llms.txt","GET /privacy"],"charging":"Base price: verified before the conversion runs, and settled on-chain when the response is successful, or earlier, just before a browser render starts (render=browser, or render=auto on a page that needs it). An error before that point is never charged. If a render you asked for then fails, you were charged: the error carries your receipt, details.callerCharged = true and details.ledgerStatus. A toll quote (paymentFlow upfront) is settled before the conversion runs. If the origin then rejects the toll, or the page cannot be converted, the error carries your receipt and details.callerCharged = true. There is no automatic refund. url2md reconciles its ledger against the chain.","howToPay":"Call a paid route. The 402 carries the terms. Sign an EIP-3009 USDC transfer authorization for accepts[0].amount to accepts[0].payTo (PAYMENT-REQUIRED header, base64 JSON) and retry with it in the PAYMENT-SIGNATURE header. The payer wallet needs USDC only, no ETH: the facilitator submits the transfer and pays the gas. Header names are case-insensitive. Client libraries: @x402/fetch and @x402/axios (JavaScript, https://www.npmjs.com/package/@x402/fetch) and x402 (Python, https://pypi.org/project/x402/). EIP-3009: https://eips.ethereum.org/EIPS/eip-3009. The successful response carries a PAYMENT-RESPONSE header with the settlement transaction.","passthrough":{"enabled":true,"marginPct":25,"maxTollUsd":"0.05","payer":"0xd38a5307Ca677B2D0cd766d400d48E3f2984Eb0a","how":"When the origin itself answers 402 with x402 terms (exact scheme, USDC on eip155:8453), the first paid call answers 402 again with a quote: base price + origin toll + 25% margin, paymentFlow \"upfront\". The quote itself travels in accepts[0].extra.quote, signed by url2md, and client libraries echo it with the payment, so the retry is accepted from any location. Pay that quote and it settles first. Then url2md pays the origin from its own wallet and returns the page with X-Url2md-Upstream-Toll. Tolls above $0.05 are refused (UPSTREAM_TOLL_TOO_HIGH). Quotes are valid for 15 minutes."},"docs":"https://x402.org"},"policies":{"robots":"robots.txt is followed per RFC 9309 for the user-agent token 'url2md', falling back to '*'. An unreachable robots.txt counts as disallow","userAgent":"Mozilla/5.0 (compatible; url2md/1.4.0; +https://url2md.io)","retention":"The Markdown is never stored: it is converted, returned, and no copy is written anywhere. What is kept is the request itself. The URL you asked for, your IP and your User-Agent stay in Cloudflare's request logs for 7 days. Every paid call also writes a ledger row — the URL, your payer address, the payment's nonce and transaction, the client name and User-Agent your request sent, and what the call returned — and that row is kept indefinitely, because it is the record of what you were charged and the thing the ledger is reconciled against on-chain. Payments are on a public blockchain, so payer, amount and transaction are public and permanent regardless. A signed-in call through the hosted MCP connector writes a row too — the URL, your account id and the outcome, at $0 — kept for 90 days. If a URL is itself a secret, that is worth knowing before you send it.","limits":{"maxBytes":10485760,"maxRedirects":5,"timeoutMs":20000,"browserTimeoutMs":30000,"browserWallClockMs":55000,"worstCaseMs":75000,"clientTimeoutMs":90000,"requestsPerMinute":60,"browserRendersPerMinute":6}}}