Why switch?
ScrapeGraph v2 offers AI-powered scraping, extraction, search, crawling, and first-class scheduled monitoring through a unified API. If you’re coming from Firecrawl, this page maps every endpoint, SDK method, parameter, and response shape to its ScrapeGraph equivalent so you can migrate quickly and confidently. The migration is mechanical for most workloads: change a header, swap an import, and adjust one or two argument names. The places that need genuine rethinking are change tracking (now a first-classmonitor resource) and browser actions (replaced by a simpler fetchConfig model).
Feature comparison at a glance
Authentication
The header name is the most common source of migration bugs —
SGAI-APIKEY is not a Bearer token.
SDK installation
Migration checklist
Quick cURL sanity check
ApiResult envelope on the raw HTTP endpoint — the SDKs add that client-side):
Common gotchas
- Header name. It’s
SGAI-APIKEY: sgai-..., notAuthorization: Bearer .... Watch for proxies that normalize header casing — the API tolerates any case, but some HTTP libraries strip non-standard headers in redirects. schemafield name in Python.JsonFormatConfigandextractuseschema=(the field is internally aliased fromschema_to avoid shadowing theBaseModel.schemamethod — passschema=from your code and it works).- No
actionsarray. If you relied onclick/type/pressactions, you’ll need to either split the flow into two scrapes (one to trigger a navigation that produces a stable URL, one to scrape the result) or contact support about the upcominginteractionsAPI. - Crawl is always async. There is no blocking
sgai.crawl(...)— callcrawl.startand poll, or pass awebhookUrlvia amonitorinstead. changeTrackingis gone as a format. Usemonitor.create— it gets you cron scheduling, persistent history, and webhook delivery in one resource.- Response shape per format. Each requested format lives under
results[<format>].data(always an array). For most formats the array has one element; forlinksandimagesit’s the full list. numResultscaps at 20 for search. Firecrawl’slimitaccepts higher values — split the query (e.g., bytimeRange) if you need more.