v2.9.0
Added 13
- Browser interaction via `/interact` endpoint to take actions on pages such as clicking buttons, filling forms, and navigating, with support for natural language prompts and Playwright code
- Query format to the `/scrape` endpoint that accepts a natural-language prompt and returns a direct answer in `data.answer`
- Audio format option to scrape responses, returning audio output as a field on the document
- onlyCleanContent parameter to the `/scrape` endpoint to strip navigation, ads, cookie banners, and other non-semantic content from markdown output
- PDF parsing modes (fast, auto, ocr) and maxPages option to control extraction depth and OCR behavior
- Official Java and Elixir SDKs with full v2 API support
- Support for parsing legacy .doc files
- Dedicated Wikimedia engine for scraping Wikipedia and Wikimedia pages with improved output quality
- contentType field in scrape responses for PDFs and documents
- GET /v2/team/activity endpoint for listing recent scrape, crawl, and extract jobs with cursor-based pagination
- regexOnFullURL parameter on crawl requests to apply includePaths/excludePaths filtering against the full URL including query parameters
- deduplicateSimilarURLs parameter on crawl requests
- v2 API namespace with agent support to the Rust SDK
Changed 7
- Persistent browser profiles now support saving and reusing browser state (cookies, localStorage) across scrapes
- PDF pipeline with improved table detection, header/footer stripping, mixed PDF handling, inline image parsing, and magic byte detection
- Branding extraction to skip hidden DOM elements for cleaner output
- HTML-to-markdown conversion performance
- Concurrency queue system with reconciler and backfill for more reliable job scheduling
- Renamed persistentSession to profile on browser/interact requests, with writeMode renamed to saveChanges
- Job timeouts are now capped at 48 hours to prevent runaway jobs from consuming resources
Fixed 14
- Python SDK parameters timeout, max_retries, and backoff_factor are now properly applied instead of being silently ignored
- Empty responses when using the o3-mini model on extract jobs
- Revoked API keys remaining valid for up to 10 minutes after deletion
- Race condition in extract jobs that caused Job not found crashes
- time_taken in /v1/map always returning approximately 0
- Crawl status responses now surface a failed status with an error message and partial data when a crawl-level failure occurs
- maxPages not being passed to the PDF extractor, which was returning full PDF content while only charging for the limited page count
- Free request credits being incorrectly consumed and billed on agent jobs exceeding the maxCredits threshold
- Dashboard displaying incorrect concurrency limits due to stale reads
- Branding colors.secondary not being populated
- removeBase64Images running after deriveDiff in the transformer pipeline, causing diff issues
- GCS fetch using wrong row index for cache info lookups
- Unhandled ZodError in /v1/search controller
- Code blocks losing content during HTML-to-markdown conversion
Deprecated 1
- Extract endpoint in favor of the /agent endpoint
Security 2
- Resolved multiple CVEs across dependencies including handlebars, path-to-regexp, fast-xml-parser, rollup (CVE-2026-27606), and undici
- Hardened the Playwright service against SSRF attacks
Firecrawl v2.9.0
Improvements
- Browser Interaction via
/interactendpoint — Scrape a page, then call/interactto take actions on it — click buttons, fill forms, navigate deeper, or extract dynamic content. Describe what you want in natural language viaprompt, or write Playwright code (Node.js, Python) and Bash (agent-browser) for full control. Sessions persist across calls, with live view and interactive live view URLs for real-time browser streaming. Persistent profiles let you save and reuse browser state (cookies, localStorage) across scrapes. Available in JS, Python, Java, and Rust SDKs. queryformat — Addedqueryformat to the/scrapeendpoint — pass a natural-language prompt and get a direct answer back indata.answer.audioformat — Addedaudioformat option to scrape responses, returning audio output as a field on the document.onlyCleanContentparameter — AddedonlyCleanContentparameter to the/scrapeendpoint, which strips navigation, ads, cookie banners, and other non-semantic content from markdown output.- PDF parsing modes — Added PDF parsing modes (
fast,auto,ocr) and amaxPagesoption to control extraction depth and OCR behavior. - Java and Elixir SDKs — Added official Java and Elixir SDKs with full v2 API support.
- Legacy
.docfile support — Added support for parsing legacy.docfiles. - Wikimedia engine — Added a dedicated engine for scraping Wikipedia and Wikimedia pages with improved output quality.
contentTypein scrape responses — AddedcontentTypeto scrape responses for PDFs and documents.- PDF pipeline improvements — Improved PDF pipeline with better table detection, header/footer stripping, mixed PDF handling, inline image parsing, and magic byte detection.
- Branding extraction — Improved branding extraction to skip hidden DOM elements for cleaner output.
- HTML-to-markdown performance — Improved HTML-to-markdown conversion performance and fixed code blocks losing content during conversion.
- Concurrency queue — New concurrency queue system with reconciler and backfill for more reliable job scheduling.
- Rust SDK v2 — Added v2 API namespace with agent support to the Rust SDK.
- Fixed Python SDK parameters
timeout,max_retries, andbackoff_factor— these were previously accepted but silently ignored. - Capped job timeouts at 48 hours to prevent runaway jobs from consuming resources.
- Added retry limits to prevent scrape loops.
- Binary content types are now rejected early in the scrape pipeline to avoid wasted processing.
Fixes
- Fixed empty responses when using the
o3-minimodel on extract jobs. - Fixed revoked API keys remaining valid for up to 10 minutes after deletion.
- Fixed a race condition in extract jobs that caused "Job not found" crashes.
- Fixed
time_takenin/v1/mapalways returning ~0. - Fixed crawl status responses now surfacing a
failedstatus with an error message and partial data when a crawl-level failure occurs. - Fixed
maxPagesnot being passed to the PDF extractor — previously, full PDF content was returned while only charging for the limited page count. - Fixed free request credits being incorrectly consumed and billed on agent jobs exceeding the
maxCreditsthreshold. - Fixed dashboard displaying incorrect concurrency limits due to stale reads.
- Fixed branding
colors.secondarynot being populated. - Fixed
removeBase64Imagesrunning afterderiveDiffin the transformer pipeline, causing diff issues. - Fixed GCS fetch using wrong row index for cache info lookups.
- Fixed unhandled
ZodErrorin/v1/searchcontroller. - Resolved multiple CVEs across dependencies including
handlebars,path-to-regexp,fast-xml-parser,rollup(CVE-2026-27606),undici, and others. - Hardened the Playwright service against SSRF attacks.
API
- Added
GET /v2/team/activityendpoint for listing recent scrape, crawl, and extract jobs with cursor-based pagination (last 24 hours, up to 100 results per page, filterable by endpoint type). - Added
regexOnFullURLparameter on crawl requests to applyincludePaths/excludePathsfiltering against the full URL including query parameters. Available in JS, Python, Java, and Elixir SDKs. - Added
deduplicateSimilarURLsparameter on crawl requests. Available in JS, Python, Java, and Elixir SDKs. - Deprecated the
extractendpoint — use the/agentendpoint instead. Existingextractmethods in JS and Python SDKs are marked deprecated. - Renamed
persistentSessiontoprofileon browser/interact requests (writeModeis nowsaveChanges). The old parameter name remains functional but is no longer documented.
New Contributors
- @misza-one made their first contribution in https://github.com/firecrawl/firecrawl/pull/2660
- @madmikeross made their first contribution in https://github.com/firecrawl/firecrawl/pull/2948
- @rowinsg made their first contribution in https://github.com/firecrawl/firecrawl/pull/3065
- @Bortlesboat made their first contribution in https://github.com/firecrawl/firecrawl/pull/3243
- @dagecko made their first contribution in https://github.com/firecrawl/firecrawl/pull/3249
- @cokemine made their first contribution in https://github.com/firecrawl/firecrawl/pull/3262
- @paulonasc made their first contribution in https://github.com/firecrawl/firecrawl/pull/3275
Contributors
- @nickscamara
- @mogery
- @amplitudesxd
- @abimaelmartell
- @ericciarla
- @rafaelsideguide
- @delong3
- @devhims
- @Chadha93
- @tomsideguide
- @charlietlamb
- @developersdigest
- @micahstairs
- @rhys-firecrawl
- @firecrawl-spring
- @devin-ai-integration
- @misza-one
- @madmikeross
- @rowinsg
- @Bortlesboat
- @dagecko
- @cokemine
- @paulonasc
Full Changelog: https://github.com/firecrawl/firecrawl/compare/v2.8.0...v2.9.0