# url2md > PDFs, JavaScript-rendered pages and ordinary HTML, returned as clean Markdown. Follows robots.txt per RFC 9309. url2md takes payment per call over the x402 protocol (v2, scheme `exact`) instead of an API key, so an agent can use it with no account and no human signup. ## Price - **$0.005 per call** (`5000` atomic USDC), about 200 pages per dollar - USDC on Base (`eip155:8453`), asset `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` - Paid to `0xa09aE66Ec8664475697FfC0eb45aa3Fe52Aa6030`, settled through https://api.cdp.coinbase.com/platform/v2/x402 - If the page itself charges an x402 toll, url2md quotes base + toll + 25%, settles your payment first and then pays the origin from its own wallet. Tolls above $0.05 are refused (`UPSTREAM_TOLL_TOO_HIGH`). ## When you are charged 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. ## Endpoints - `GET /v1/md`, `POST /v1/md` (paid): convert a URL to Markdown. Parameters: `url` (required), `render` (auto (default) | static | browser), `format` (json (default) | markdown. Or send Accept: text/markdown). - `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`: free. ## Calling it ``` curl -i 'https://url2md.io/v1/md?url=https://example.com' # 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. curl -i -H 'PAYMENT-SIGNATURE: ' -H 'Accept: text/markdown' 'https://url2md.io/v1/md?url=https://example.com' # 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. ``` ## From an MCP client - `@url2md-io/mcp`: a stdio (local) MCP server with one tool, `fetch_markdown`. Send it a URL, get back Markdown plus the settlement receipt. It pays with your wallet, so it can pay a page's x402 toll too. - 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. - Setup and the full tool reference: https://www.npmjs.com/package/@url2md-io/mcp - Hosted connector: `https://url2md.io/mcp`, Streamable HTTP (hosted), OAuth 2.1 with PKCE (S256) and a GitHub sign-in, with dynamic client registration or a client ID metadata document. For clients that hold no wallet. Free to the signed-in account: 100 calls per 30 days, at most 20 of them browser renders, and 2000 calls a day across every account. Tolls are 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. In claude.ai: Customize → Connectors → Add custom connector → paste the URL → Add → Connect → sign in with GitHub. ## Docs - [OpenAPI 3.1](https://url2md.io/openapi.json): the canonical contract, with every route, parameter, response and error code - [This service as JSON](https://url2md.io/?format=json): price, network, addresses, policies and limits, live - [@url2md-io/mcp on npm](https://www.npmjs.com/package/@url2md-io/mcp): the local MCP server. Its README is the full setup and tool reference - [x402](https://x402.org): the payment protocol - [What is kept](https://url2md.io/privacy): the privacy policy, covering what is stored, for how long, and who else sees it ## What is kept 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 and policies - robots.txt is followed per RFC 9309 for the user-agent token 'url2md', falling back to '*'. An unreachable robots.txt counts as disallow - User-Agent: `Mozilla/5.0 (compatible; url2md/1.4.0; +https://url2md.io)` - 60 requests per minute per client IP, of which 6 may be browser renders - 10 MB per page, 5 redirects - Set your own timeout to 90s. What the service enforces: 20s for the fetch (robots.txt, every redirect hop and the body on one deadline) and 55s for a browser render (30s navigation + 25s action and slack), so a render=browser call is bounded at 75s. Contact: hello@url2md.io