# WebExtract > Web page → clean Markdown + fixed-schema JSON (article metadata, product/price, tables) for AI agents. Respects robots.txt. GET https://api.webextract.dev/v1/extract?url= Markdown + structured JSON (1 credit, or $0.005 via x402) GET https://api.webextract.dev/v1/markdown?url= Markdown only (0.4 credit, or $0.002 via x402) POST works too: send {"url": ""} as JSON (or form) body to the same paths. GET https://api.webextract.dev/v1/balance (remaining credits, or free calls left today) Free tier is opt-in on REST: send header X-Billing: free (or ?free=1) for 50 calls/day per IP (X-Free-Remaining header, returned only in free mode). Without a key, payment or X-Billing: free, REST answers HTTP 402 (reason x402_required). MCP: 50 free calls/day per IP, no header needed. curl -H "X-Billing: free" "https://api.webextract.dev/v1/markdown?url=https://example.com" Prepaid: Authorization: Bearer . Packs: $5 = 1000 calls, $20 = 5000 calls, $50 = 15000 calls. Buy: https://webextract.dev/#pricing (Stripe Checkout; API key shown once after payment) No account? Pay per call with x402 v2 in USDC on Base (recommended), Polygon, Arbitrum One, World Chain, Monad, Avalanche C-Chain or OP Mainnet (eip155:8453, eip155:137, eip155:42161, eip155:43114, eip155:10, eip155:480, eip155:143). A plain request without a key already gets the 402 with requirements (X-Billing: x402 does the same explicitly). A payment header always wins over X-Billing: free; a Bearer key wins over both. HTTP 402 = payment required. JSON body has "reason": x402_required (no key/payment/opt-in) | x402_requested (X-Billing: x402) | free_limit_reached (opted into free, quota used) | invalid_payment | unsupported_network | settlement_failed (payment verified but not settled; not charged, retry with a new payment) (also in the X-Payment-Reason header); requirements are in the PAYMENT-REQUIRED header; retry with PAYMENT-SIGNATURE. Discovery: https://api.webextract.dev/.well-known/x402 Errors: 400 missing/invalid url or unknown X-Billing value · 401 bad key · 402 payment required / out of credits · 413 too large · 415 unsupported type · 422 site blocked · 451 robots.txt disallow. All errors are JSON and not charged. Sandbox (free test money only): https://api.webextract.dev/sandbox/v1/extract and /sandbox/v1/markdown, or header X-Billing: x402-testnet on /v1/*. Accepts only Base Sepolia (eip155:84532) test USDC 0x036CbD53842c5426634e7929541eC2318f3dCF7e via the x402.org testnet facilitator (faucet: https://faucet.circle.com). Rate limited per IP (HTTP 429). Credits never expire. No charge on failed fetches (404, timeout, blocked, robots.txt disallowed). Structured JSON at no extra cost. If structured fields come back empty with a prepaid key, you're only charged the Markdown rate. x402 settles at the quoted price, only when the request succeeds. Prices: read product.price_detail (currency, type list|sale|current, matched variant; never 0 — status "unresolved" comes with unresolved.reason). content_source says raw_html (no JavaScript run) or rendered; product.source is the extraction method. Listing/category pages return product: null with product_unresolved.reason "listing_page". MCP (streamable-http): POST https://api.webextract.dev/mcp tools: extract_url, page_markdown (server card: https://api.webextract.dev/.well-known/mcp/server-card.json) Docs: https://api.webextract.dev/docs Vercel AI SDK tools (npm @webextract/ai-sdk): https://api.webextract.dev/docs/ai-sdk LangChain tools (PyPI langchain-webextract, npm @webextract/langchain): https://api.webextract.dev/docs/langchain OpenAPI: https://api.webextract.dev/openapi.json Terms: https://api.webextract.dev/terms Privacy: https://api.webextract.dev/privacy Refunds: https://api.webextract.dev/refunds