Every founder who's built something that reads the web has met the same wall: the scraper. You write it in an afternoon, it works on three sites, and then it breaks on the fourth because the content is behind JavaScript, or the HTML is a nest of <div>s, or the site changed its layout overnight. You end up maintaining infrastructure that has nothing to do with your actual product.
Firecrawl is the tool that deletes that job. Point it at a URL; get back clean markdown a model can read.
What it is#
Firecrawl is a developer-first API that turns websites into LLM-ready data. It returns clean markdown by default — sized for context windows — and can also give you raw HTML, screenshots, page metadata, or structured JSON against a schema you define. The key detail: it renders JavaScript automatically, so single-page apps and dynamically loaded sites just work, with no headless-browser plumbing on your side.
It exposes five endpoints, which between them cover almost every "get the web into my model" task:
- Scrape — one URL → markdown/JSON.
- Crawl — a whole site, following links.
- Map — return every URL on a site (great for building a sitemap before a targeted crawl).
- Search — web search that returns full page content, not just links.
- Interact — browser automation for pages that need clicks or logins.
Who it's for#
- RAG / knowledge-app builders who need to ingest docs, help centers, or public pages without writing per-site parsers.
- Agent builders who want a
searchthat returns readable content instead of a list of blue links. - Solo founders doing competitor tracking, lead research, or market monitoring who'd rather call an API than babysit Puppeteer.
How to start#
The hosted API is the fastest path. Grab a key at firecrawl.dev, then scrape a page in one call:
curl -X POST https://api.firecrawl.dev/v2/scrape \
-H "Authorization: Bearer fc-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "formats": ["markdown"]}'
Or from Python:
from firecrawl import Firecrawl
app = Firecrawl(api_key="fc-YOUR_KEY")
# One page → clean markdown, ready for a prompt
doc = app.scrape("https://example.com", formats=["markdown"])
print(doc.markdown)
# Whole site → a list of pages you can chunk and embed
job = app.crawl("https://docs.example.com", limit=50)
for page in job.data:
index_into_your_vector_db(page.markdown)
Want structured data instead of prose? Pass a schema and Firecrawl runs LLM-based extraction during the crawl:
schema = {
"type": "object",
"properties": {
"product_name": {"type": "string"},
"price": {"type": "number"},
},
}
result = app.scrape("https://store.example.com/item/42",
formats=[{"type": "json", "schema": schema}])
print(result.json) # -> {"product_name": "...", "price": 19.0}
If you'd rather not send traffic through a third party, Firecrawl is open source under AGPL and self-hosts via Docker; the core scrape/crawl features are all there. The hosted tier adds higher concurrency, managed infrastructure, and the LLM extract endpoint.
What it costs#
The hosted plans, as of mid-2026:
- Free — $0, 1,000 credits/month. Enough to prototype.
- Hobby — $16/mo (billed yearly), 5,000 credits.
- Standard — $83/mo, 100,000 credits.
- Growth — $333/mo, 500,000 credits.
- Scale — $599/mo, 1,000,000 credits.
- Enterprise — custom.
Self-hosting is free of license cost (AGPL) — you pay for your own compute and the maintenance you were trying to avoid, so it's the right call only at real scale or under strict data-residency rules.
The takeaway#
If your product's value is what you do with web content, Firecrawl lets you skip the part that was never your product — acquiring and cleaning it. Start on the free tier, wire scrape into one feature this week, and see how much scraper code you get to delete.



