# PennyOCR > OCR API for developers and agents: POST a document (PDF/PNG/JPEG/WebP/TIFF), > get its full text back as markdown (tables preserved) or plain text. > $0.75 per 1,000 pages, first 100 pages/month free. Zero data retention by default. ## MCP server (recommended for agents) Add to mcpServers: {"pennyocr": {"url": "https://mcp.pennyocr.com", "headers": {"Authorization": "Bearer pk_live_..."}}} Tools: read_document {url, pages?, output?, max_pages?, max_cost_usd?} -> {content, pages, cost_usd, citations[]} · estimate_cost {url, pages?} (free). Clients without header support: https://mcp.pennyocr.com/?key=pk_live_... ## API (base: https://api.pennyocr.com) - POST /v1/ocr — multipart form, field `file`; query `?format=markdown|text`; header `Authorization: Bearer pk_live_...`. Response JSON: {id, pages, text, page_results[], cost_usd, model}. Errors: 401 bad key, 402 out of credits, 413 too large (50MB/500 pages), 422 unreadable. - POST /v1/chat/completions — OpenAI Chat Completions compatible. Send image_url content parts (data: or https URLs); model "pennyocr-markdown" or "pennyocr-text". - GET /v1/models — OpenAI-style model list. - POST /v1/ocr/url — JSON {url, format?, pages?, max_pages?, max_cost_usd?}; fetches the document server-side. 413 (with exact numbers) if a cap would be exceeded — decide, then retry. - POST /v1/estimate — JSON {url, pages?} -> {total_pages, selected_pages, cost_usd}. Free. - GET /health — status, no auth. - Machine-readable spec: https://api.pennyocr.com/openapi.yaml (and /openapi.json) ## Signup for agents (no browser needed) 1. POST https://api.pennyocr.com/auth/request-code {"email": "you@example.com"} 2. Read the 6-digit code from that inbox, then POST https://api.pennyocr.com/auth/verify {"email": "...", "code": "123456"} -> {"session_token": "sk_session_..."} 3. POST https://api.pennyocr.com/dashboard/keys (Authorization: Bearer ) -> {"api_key": "pk_live_..."} (shown once) 4. You now have 100 free pages/month. To buy prepaid credits: POST https://api.pennyocr.com/dashboard/billing/checkout {"pack": "10k" | "100k" | "1m"} (Authorization: Bearer ) -> {"url": "https://checkout.stripe.com/..."} (complete payment there; a human card holder must finish Stripe checkout) 5. Usage: GET /dashboard/usage · daily series: GET /dashboard/usage/daily ## Pricing - /pricing.txt: plain-text pricing summary - https://pennyocr.com/ocr-api-pricing/: pricing comparison page ## Docs - https://pennyocr.com/docs/: full API reference - https://pennyocr.com/blog/receipt-ocr-benchmark/: measured accuracy benchmark ## Contact - hello@pennyocr.com (a human replies fast)