Open-source, Cloudflare-native, and drop-in compatible with the Firecrawl v2 API. Scrape, crawl, map, search, extract, and parse the web — then point your client at crawl.cheap and keep your code.
# Scrape any page to clean Markdown — no signup curl -X POST https://api.crawl.cheap/v2/scrape \ -H 'content-type: application/json' \ -d '{"url":"https://example.com", "formats":["markdown","links"]}' # → { "success": true, "data": { "markdown": "…" } }
crawl.cheap speaks the Firecrawl v2 contract — same request bodies, same response shapes, same error envelope. The official @mendable/firecrawl-js and firecrawl-py SDKs run unchanged (verified 8/8 + 4/4 against production).
// @mendable/firecrawl-js — change the constructor, keep every call - const app = new Firecrawl({ apiKey: 'fc-...' }); + const app = new Firecrawl({ apiKey: 'cc_live_...', apiUrl: 'https://api.crawl.cheap' }); await app.scrape('https://example.com', { formats: ['markdown'] }); // unchanged
# firecrawl-py — same client, new api_url + key - app = Firecrawl(api_key="fc-...") + app = Firecrawl(api_key="cc_live_...", api_url="https://api.crawl.cheap") app.scrape("https://example.com", formats=["markdown"]) # unchanged
# Raw REST — swap the host and the bearer token - curl https://api.firecrawl.dev/v2/scrape -H 'Authorization: Bearer fc-...' + curl https://api.crawl.cheap/v2/scrape -H 'Authorization: Bearer cc_live_...'
Your existing Firecrawl key is never automatically valid — issue a crawl.cheap key (free, instant, below). The FIRECRAWL_API_URL / FIRECRAWL_API_KEY env conventions are honored too.
This calls the real production API from your browser (rate-limited demo). Clean Markdown out, powered by Cloudflare Workers.
Static HTTP fetch → readability extraction → HTML→Markdown for free. Escalates to a rendered browser only when a page truly needs JS, actions, or a screenshot. Margin by design.
Markdown, HTML, links, summary, and schema-guided JSON via Workers AI.
Async multi-page crawl on a Durable Object — robots-aware, resumable, cancelable.
Enumerate a site's URLs from sitemaps + link discovery in one call.
Web / news / images search with optional result-scraping + time filters.
Structured JSON across many URLs, guided by your prompt + JSON Schema.
Autonomous research runs, plus scheduled change monitoring with signed webhook alerts.
Persistent Puppeteer sessions — click, type, scroll across requests. Metered by the minute.
Firecrawl-compatible firecrawl_* tools over Streamable HTTP for Claude, Cursor & co.
A transactional D1 ledger is the live authority for balance + usage — with enforced spend ceilings, user-set hard limits, and a deterministic /v2/quote that bounds cost before any job runs. Not an eventually-consistent meter.
Managed-edition plans at exactly half of Firecrawl's month-to-month price, with like-for-like included credits. Self-hosting is free forever on your own Cloudflare account.
Core credits bill identically to Firecrawl — your plan simply costs less per credit. "50% less" is measured vs Firecrawl's month-to-month pricing (checked 2026-10-09); their annual-billed equivalents are $16 / $83 / $333 / $599, and crawl.cheap is cheaper even against those. One-time credit packs (no subscription) start at $5 for 2,000 credits. Managed billing runs in Stripe test mode — not yet charging real cards.
A deterministic preflight quote from the live API — credits, dollars at your plan rate, and a firm ceiling. Open-ended jobs must carry a cap: crawl.cheap never runs an unbounded-cost job.
| Endpoint | Status | Engine |
|---|---|---|
POST /v2/scrape | ● live | static + browser tier + Workers AI json |
POST /v2/map | ● live | sitemap + link discovery |
POST /v2/crawl (+status/cancel/errors) | ● live | Durable Object coordinator |
POST /v2/batch/scrape | ● live | Durable Object (fixed frontier) |
POST /v2/extract (+status) | ● live | Workers AI |
POST /v2/search (web/news/images) | ● live | pluggable provider + scrape + tbs |
POST /v2/parse | ● live | unpdf / HTML / text |
POST /v2/agent (+status) | ● live | web-search + scrape + AI synthesis |
POST /v2/monitor (+run/checks/webhook) | ● live | cron sweep + change diff + signed alerts |
POST /v2/browser · /:id/act (interact) | ● live | persistent Puppeteer session (DO) |
POST /v2/ai-search/* (RAG) | ● live | Vectorize + Workers AI |
GET /v2/pricing · POST /v2/quote | ● live | price book + preflight estimate |
Remote MCP (/v2/mcp, /v2/mcp-search) | ● live | createMcpHandler-style, stateless · ~13 tools |
| Stripe subscriptions + one-time credit packs | ◐ planned | built behind the ledger; awaiting a Stripe test key |
curl -X POST https://api.crawl.cheap/v2/keys \ -d '{"name":"my-app"}' # → { "apiKey": "cc_live_…", "monthlyCredits": 1000 }
# TypeScript const r = await fetch('https://api.crawl.cheap/v2/crawl', { method:'POST', headers:{ authorization:`Bearer ${key}` }, body: JSON.stringify({ url:'https://docs.site', limit:20 }) });