Migrate from Firecrawl to fastCRW in 10 Minutes — Drop-In Guide
Migrate from Firecrawl to fastCRW with a base-URL swap. fastCRW exposes a Firecrawl-compatible REST API on /scrape, /crawl, /map, /search — keep the firecrawl-py SDK, point it at fastcrw.com, done. Endpoint mapping table + honest divergences.
Migrating from Firecrawl to fastCRW is mostly a base-URL swap: fastCRW exposes a Firecrawl-compatible REST API, so the same firecrawl-py SDK and request shapes keep working on /scrape, /crawl, /map, and /search.
Verdict
Migrating from Firecrawl to fastCRW takes about 10 minutes because fastCRW exposes a Firecrawl-compatible REST API — the same base request shape on /v1/scrape, /v1/crawl, /v1/map, and /v1/search. For most teams the move is a base-URL swap: keep the firecrawl-py SDK, point FirecrawlApp at https://fastcrw.com/api (or your self-host URL), and your call sites stay the same.
This page is honest about what does not carry over. The compatibility matrix labels every gap.
Who this is for
- Teams already on Firecrawl wanting a lighter runtime — fastCRW is a single static Rust binary with no Redis, Node, or container orchestration.
- Teams hitting Firecrawl's managed pricing — fastCRW Standard is $69/mo for 100k credits versus Firecrawl Standard at $83/mo for 100k credits.
- Teams that need self-hosting — fastCRW is AGPL-3.0; the self-host build is $0/1k scrapes in license terms.
If you depend on /v1/agent, /v1/deep-research, multi-URL batched /v1/extract, screenshot output, or Fire-engine anti-bot, stay on Firecrawl Cloud — those are not matched, and this guide will tell you so plainly.
Before and after: the base-URL swap
The core of this migration is one constructor argument. Here is a typical Firecrawl scrape:
# Before — Firecrawl
from firecrawl import FirecrawlApp
app = FirecrawlApp(api_key="fc-YOUR_KEY")
result = app.scrape_url(
"https://example.com",
params={"formats": ["markdown"]},
)
print(result["markdown"])
The fastCRW version changes the base URL and the key, nothing else:
# After — fastCRW (Firecrawl-compatible)
from firecrawl import FirecrawlApp
app = FirecrawlApp(
api_key="fcrw_YOUR_KEY",
api_url="https://fastcrw.com/api", # or your self-host URL
)
result = app.scrape_url(
"https://example.com",
params={"formats": ["markdown"]},
)
print(result["markdown"])
If you call the HTTP API directly, the swap is just as small:
# Before — Firecrawl
curl -X POST https://api.firecrawl.dev/v1/scrape \
-H "Authorization: Bearer fc-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "formats": ["markdown"]}'
# After — fastCRW
curl -X POST https://fastcrw.com/api/v1/scrape \
-H "Authorization: Bearer fcrw_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "formats": ["markdown"]}'
Pin the SDK with pip install "firecrawl-py>=1,<2" so you stay on the v1 shape (FirecrawlApp, scrape_url(..., params=...)) that fastCRW targets.
Endpoint mapping table
This table maps every Firecrawl route to its fastCRW equivalent so you can audit the move before you make it. Unsupported features are marked honestly. (Endpoint surface verified 2026-05-22; re-verify the live route list before quoting.)
| Firecrawl endpoint / param | fastCRW equivalent | Migration note |
|---|---|---|
POST /v1/scrape | POST /v1/scrape | Same request shape. Costs 1 credit (2 for the chrome renderer). |
POST /v1/crawl | POST /v1/crawl | Async → returns a job id. Costs 1 credit per page. |
GET /v1/crawl/{id} | GET /v1/crawl/{id} | Same job-status contract. DELETE /v1/crawl/{id} cancels. |
POST /v1/map | POST /v1/map | Same shape. Costs 1 credit. |
POST /v1/search | POST /v1/search | SearXNG-backed; costs 1 credit per query. |
POST /v1/extract (single URL) | POST /v1/extract | Managed-cloud-only, 5-credit wrapper over /v1/scrape with formats: ["json"]. |
POST /v1/extract (multi-URL batch) | (no equivalent) | Iterate /v1/scrape concurrently or use /v1/crawl. |
POST /v1/batch/scrape | (no equivalent) | There is no batch endpoint — iterate /v1/scrape or use /v1/crawl. |
formats: ["screenshot"] | (not supported) | Returns HTTP 422. fastCRW has no screenshot output. |
POST /v1/agent (Spark models) | (no equivalent) | Firecrawl-Cloud-only. Stay on Firecrawl if central. |
POST /v1/deep-research | (no equivalent) | Firecrawl-Cloud-only. |
engine param | renderer param (engine accepted as alias) | Renderers: auto, http, lightpanda, chrome. |
limit / maxPages on crawl | maxPages (limit, max_pages are serde aliases) | Also accepts maxDepth for depth control. |
| Fire-engine anti-bot | (no equivalent) | fastCRW falls back to a chrome-stealth renderer, not Fire-engine. |
| LLM extraction provider | OpenAI + Anthropic only | formats: ["json"] extraction supports these two providers. |
GET /v1/health style check | GET /health | Liveness probe. |
Step-by-step migration
The numbered steps below mirror the howToSteps schema for this page.
1. Audit your Firecrawl endpoint usage
Grep your codebase for Firecrawl calls. List which routes you hit — scrape, crawl, map, search, extract — and flag any screenshot output or multi-URL batched extract. Those flagged calls are the only ones that need rework.
2. Provision a fastCRW API key
Visit fastcrw.com, sign up, and copy your key (it starts with fcrw_). The Free tier ships 500 one-time lifetime credits that never reset. If you self-host the AGPL-3.0 build, you can skip this — auth is optional in self-host mode.
3. Point your SDK at the fastCRW base URL
Set api_url="https://fastcrw.com/api" on FirecrawlApp (or your self-host URL). This is the load-bearing change — your scrape_url, crawl_url, and search call sites stay identical.
4. Pin the SDK version
Run pip install "firecrawl-py>=1,<2". The v1 SDK shape — FirecrawlApp, scrape_url(..., params=...) — is what fastCRW's Firecrawl-compatible surface targets. Pinning prevents a future v2 SDK from shifting the contract under you.
5. Run your test suite and adjust diverged fields
Run your existing tests against fastCRW. The request shape matches, but response field names and error envelopes have minor divergences (notably parts of the metadata object). Adjust any code that reads those specific keys. Most call sites need no change.
6. Replace unsupported feature calls
Any formats: ["screenshot"] call returns HTTP 422 — remove it or render screenshots elsewhere. Replace multi-URL batched /v1/extract with a concurrent /v1/scrape loop or /v1/crawl. There is no /v1/batch/scrape to fall back to.
7. Verify in the playground, then cut over
Test your target URLs in the playground across all four overlap endpoints. Confirm the response shape works for your parser before you flip production traffic.
What does not carry over
Be explicit with your team about these divergences before you migrate:
- No screenshot output.
formats: ["screenshot"]returns HTTP 422. - No multi-URL batched extract.
/v1/extractis single-URL, managed-cloud-only, and costs 5 credits. For batches, iterate/v1/scrapeor use/v1/crawl. - No
/v1/agentand no/v1/deep-research. These are Firecrawl-Cloud-only. - No Fire-engine anti-bot. fastCRW recovers hard URLs with a chrome-stealth renderer fallback — that fallback is the disclosed cause of the worst-case p90 of 14157 ms in the benchmark below.
- Stateless. No persistent browser sessions.
- LLM extraction is OpenAI + Anthropic only.
- Response field names and error envelopes diverge slightly. The API is compatible, not byte-identical.
Performance and pricing context
On Firecrawl's public scrape-content-dataset-v1 (1,000 URLs, 819 labeled; diagnose_3way.py, 2026-05-08), fastCRW reached 63.74% truth-recall of 819 labeled URLs versus Firecrawl's 56.04%, with a p50 of 1914 ms versus Firecrawl's 2305 ms across 3,000 requests with 0 errors. The honest tail: fastCRW's p90 is 14157 ms — the worst of the three, and the disclosed cost of the chrome-stealth fallback that recovers hard URLs. Read the methodology before quoting these numbers.
On price, fastCRW Standard is $69/mo for 100k credits versus Firecrawl Standard at $83/mo for 100k credits; the AGPL-3.0 self-host build is $0 in license terms. Launch pricing (Hobby $13/mo) ends 2026-06-01.
Related
Continue exploring
More from Integrations
Claude Code Web Scraping Integration — fastCRW [MCP Server]
CrewAI Web Scraping Integration — fastCRW [Firecrawl-Compatible]
Migrate from Tavily to fastCRW — Search API Migration Guide
Migrate from Tavily search API to fastCRW POST /v1/search. fastCRW search averaged 880 ms across a 100-query benchmark, and adds scrape, crawl, and map. Param mapping table, before/after code, and honest gaps (BYOK-only answer synthesis, no domain filters).
Cursor Web Scraping Integration — fastCRW [Firecrawl-Compatible]
Add fastCRW as an MCP server in Cursor IDE. Configure ~/.cursor/mcp.json, then scrape, search, crawl, and map web pages from within your agent prompts. A single static Rust binary, local-first.
Migrate from Jina Reader to fastCRW — URL-to-Markdown Upgrade Guide
Migrate from Jina Reader (r.jina.ai URL-prefix) to fastCRW POST /v1/scrape. Same clean markdown plus crawl, map, search, LLM extraction, JS rendering, and AGPL-3.0 self-hosting on a single Rust binary. Before/after code + endpoint mapping.
Related hubs