<!-- twin of https://specstream.ai/migrate/firecrawl -->
# Firecrawl migration: change the base address, keep search and scrape

Compared on Nov 10, 2026. The page: https://specstream.ai/migrate/firecrawl

Since November 9, 2026 SpecStream answers Firecrawl v2 search and scrape at `https://api.specstream.ai/firecrawl`, in Firecrawl's JSON. A search costs $0.005 for up to 10 results and a scrape $0.0008 a page, from a balance, with no monthly plan.

Change `https://api.firecrawl.dev` to `https://api.specstream.ai/firecrawl` and send a SpecStream key as the Bearer token. `POST /v2/search` and `POST /v2/scrape` keep their bodies.

97.9 F-score on all 1,000 SimpleQA Verified questions for search, and 0.908 F1 on WCXB for the Extract API that answers each scrape, on the [benchmarks](https://specstream.ai/benchmarks?utm_source=alternatives&utm_campaign=migrate-firecrawl) page.

[Get an API key](https://specstream.ai/signup?src=alternatives-migrate-firecrawl&utm_source=alternatives-md&utm_campaign=migrate-firecrawl&returnTo=%2Fworkspace%2Fsearch%3Froute%3Dfirecrawl) New accounts get $10 of credit, no card. It covers 2,000 searches.

## Firecrawl v2 to SpecStream, parameter by parameter and field by field

| | SpecStream (`/firecrawl/v2`) | Firecrawl |
|---|---|---|
| Address | `https://api.specstream.ai/firecrawl`, so the calls are `POST /firecrawl/v2/search` and `POST /firecrawl/v2/scrape`. A setting that holds the version takes `https://api.specstream.ai/firecrawl/v2` | `https://api.firecrawl.dev`, with `POST /v2/search` and `POST /v2/scrape` |
| Key | Your SpecStream key as `Authorization: Bearer`, or as the HTTP Basic password. No key gets a `401` | Your Firecrawl key as `Authorization: Bearer` |
| Search: `query` and `limit` | Read. `limit` is 1 to 100, default 5. Up to 10 results cost $0.005 and run the fast search; 100 cost $0.059 | The search body with `query` and `limit`. A search takes 2 credits |
| Search: `includeDomains`, `excludeDomains`, `tbs` | Read as site filters and as a date filter (`qdr:` or `cdr` with `cd_min` and `cd_max`) | Fields of the search body |
| Search: `scrapeOptions.formats` with `markdown` | Read. Each result then carries `markdown`: the text of its page closest to the query, up to about 3,500 characters, and `metadata`. Same price; it runs the default search | Asks for each result's page as `markdown`, as LobeHub sends it with a `limit` of 20 |
| Search: `timeout`, `ignoreInvalidURLs` and other fields | Accepted with no error and not used | Fields Open WebUI sends with its search |
| Search reply | `success: true`, `data.web[]` with `url`, `title`, `description` and `position`, `id`, and `specstream` with the price of the call. `data.web` is the only list in `data` | `success: true` and `data.web[]` with `url`, `title` and `description`, and `markdown` when asked |
| Scrape: `url` | Read. One page or document (PDF, Word, Excel) through the Extract API. Other `formats` are accepted; the reply is markdown | The page to scrape, with the `formats` you want back |
| Scrape reply | `success: true`, `data.markdown` (the main text, without menus, footers and ads) and `data.metadata` with `sourceURL`, `url`, `statusCode`, `title` and `publishedTime` when the page gives one. `data.html` and `data.rawHtml` are not returned | `data.markdown`, `data.html`, `data.rawHtml` and `data.metadata` |
| A page that gives no text | `success: false` with a `500` and the reason, and nothing is charged. A page that refuses a plain read is tried as a browser would ask, then in a real browser, then from the site's feed, then from its newest archive capture | `success: false` with an `error` |
| Price | $0.005 a search of up to 10 results and $0.0008 a page, paid from a balance. Credit you top up never expires | Monthly plans in credits: Hobby $19 a month for 5,000, Standard $99 a month for 100,000, Scale $749 a month for 1,000,000 |
| Before you pay | $10 of credit on sign up, no card: 2,000 searches or 12,500 pages | A free plan of 500 searches or 1,000 pages scraped, at 10 requests a minute |

## What changes and what stays when you move from Firecrawl

### The whole migration is the base address and the key

Your code keeps Firecrawl's paths, bodies and parser. The base address changes, and the Bearer key.

```
# Before
curl -X POST https://api.firecrawl.dev/v2/search \
  -H "Authorization: Bearer $FIRECRAWL_API_KEY" -H "Content-Type: application/json" \
  -d '{"query": "open source vector databases", "limit": 5}'

# After
curl -X POST https://api.specstream.ai/firecrawl/v2/search \
  -H "Authorization: Bearer $SPECSTREAM_API_KEY" -H "Content-Type: application/json" \
  -d '{"query": "open source vector databases", "limit": 5}'

# A scrape is one Extract API page, $0.0008
curl -X POST https://api.specstream.ai/firecrawl/v2/scrape \
  -H "Authorization: Bearer $SPECSTREAM_API_KEY" -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/pricing"}'
```

Firecrawl's JavaScript SDK works with its API address set to `https://api.specstream.ai/firecrawl`, and LobeHub takes `https://api.specstream.ai/firecrawl/v2`. The Python SDK, firecrawl-py, works with `api_url="https://api.specstream.ai"`, and with it the Firecrawl loaders of GPT Researcher, LangChain and LlamaIndex.

### What the reply leaves out

The route answers search and scrape. A search returns `data.web` only. `markdown` on a search result is the part of the page closest to the query, up to about 3,500 characters; for the whole page, scrape it. A scrape returns markdown and metadata, so `data.html` and `data.rawHtml` are not in the reply.

A refusal keeps Firecrawl's shape: `success: false` with `error` and a `code`. A missing key is a `401`, an empty balance a `402`, and a busy minute a `429` with `Retry-After` that charges nothing.

### Pay per call, with no plan to buy first

Firecrawl sells credits by month: Hobby is $19 a month for 5,000 credits and Standard $99 a month for 100,000, and a search takes 2 credits. SpecStream takes $0.005 a search and $0.0008 a page from your balance, a page with no text is not charged, and the credit you top up never expires. Every rate is on the [pricing](https://specstream.ai/pricing?utm_source=alternatives&utm_campaign=migrate-firecrawl) page.

### The most accurate web search API in the world

On SimpleQA Verified the SpecStream Search API scores 97.9 F-score on all 1,000 official questions, 978 of them correct. On WideSearch it scores 64.0 item F1 and 43.4 row F1 on all 200 official tasks. The Extract API scores 0.908 F1 on WCXB. Every score and its method is on the [benchmarks](https://specstream.ai/benchmarks?utm_source=alternatives&utm_campaign=migrate-firecrawl) page.

### About one second a search, measured under load

Every drop-in route runs the fast search unless the call asks for page text or results past the first ten. On November 9, 2026 production took 1 to 20 fast searches a second and answered 718 of 720: the median was 0.82 s at 1 search a second and 1.07 s at 20 a second, and the 95th percentile stayed between 1.09 and 1.73 s. One account takes up to 8,800 searches a minute; a call over that gets a `429` with `Retry-After` and is not charged.

### You decide what is kept, on each key

Create a key with `zero_retention` and a search made with it keeps no request text and no answer after the reply: it is not in the history, its answer is not reused for another call, and its log lines carry neither. `spend_cap_cents` is the most the key can spend.

```
curl -X POST https://api.specstream.ai/v1/account/keys \
  -H "Authorization: Bearer $SPECSTREAM_API_KEY" -H "Content-Type: application/json" \
  -d '{"name": "production", "scopes": ["account:read", "finds:spend"], "spend_cap_cents": 500000, "zero_retention": true}'
```

### Search, pages and rows on one key

The same key calls `GET /v1/web-search`, which returns up to 100 results for one search and an `answer` with the page it was read from. It reads up to 20 pages or documents a call with the [Extract API](https://specstream.ai/extract-api?utm_source=alternatives&utm_campaign=migrate-firecrawl) at $0.80 per 1,000 pages, and a page with no text is not charged. [Deep Search](https://specstream.ai/deep-search?utm_source=alternatives&utm_campaign=migrate-firecrawl) returns every match for a request in plain words as structured rows at 5¢, 15¢ or $1 a row, with a source URL on every value, and the most a run can cost is approved before it starts.

## Other options when you leave Firecrawl

### Exa

A search API from $4 per 1,000 requests, with page contents at $1 per 1,000 pages. SpecStream reads pages at $0.80 per 1,000 and answers Exa's own call at `https://api.specstream.ai/exa`.

### Tavily

Search and extract billed in credits at $0.008 a credit on pay as you go, with 1,000 free credits a month. SpecStream answers Tavily's call at `https://api.specstream.ai/tavily` at $0.005 a search.

### Brave Search API

A search API on Brave's own index at $5 per 1,000 requests, with $5 in free credits every month. It returns search results; SpecStream returns the results and reads the pages behind them on the same key.

### Serper

Google results as JSON, in credit packs from $1.00 per 1,000 that are valid for 6 months. SpecStream answers Serper's call at `https://api.specstream.ai/serper`, reads the pages too, and its top-up credit never expires.

### SerpApi

Search engine result pages as JSON, sold by monthly plan: Starter is $25 a month for 1,000 searches. On SpecStream $25 pays for 5,000 searches or 31,250 pages.

## How to move from Firecrawl

1. Create a key under Agents & API in the workspace. A new account gets $10 of credit, no card, which covers 2,000 searches.

2. Set the base address to `https://api.specstream.ai/firecrawl` where your code has `https://api.firecrawl.dev`, and send the SpecStream key as the Bearer token. In Python:

```
import os
import requests

BASE = "https://api.specstream.ai/firecrawl"  # was https://api.firecrawl.dev
HEADERS = {"Authorization": f"Bearer {os.environ['SPECSTREAM_API_KEY']}"}

found = requests.post(
    f"{BASE}/v2/search",
    json={"query": "open source vector databases", "limit": 5},
    headers=HEADERS,
).json()
for result in found["data"]["web"]:
    print(result["title"], result["url"], result["description"])

page = requests.post(
    f"{BASE}/v2/scrape",
    json={"url": found["data"]["web"][0]["url"]},
    headers=HEADERS,
).json()
print(page["data"]["metadata"].get("title"), page["data"]["markdown"][:500])
```

In JavaScript:

```
const BASE = "https://api.specstream.ai/firecrawl"; // was https://api.firecrawl.dev
const headers = {
  Authorization: `Bearer ${process.env.SPECSTREAM_API_KEY}`,
  "Content-Type": "application/json",
};

const found = await fetch(`${BASE}/v2/search`, {
  method: "POST",
  headers,
  body: JSON.stringify({ query: "open source vector databases", limit: 5 }),
}).then((response) => response.json());

for (const result of found.data.web) {
  console.log(result.title, result.url, result.description);
}
```

3. Keep `limit`, `includeDomains`, `excludeDomains` and `tbs` as they are. Add `scrapeOptions` with `formats: ["markdown"]` when you want the part of each page closest to the query in the search reply.

4. Read `data.markdown` from a scrape, and treat `data.html` and `data.rawHtml` as optional. Each reply carries the price of the call under `specstream`.

## Frequently asked questions

### What is the best Firecrawl alternative?

SpecStream, at $0.005 a search and $0.0008 a page with no monthly plan. It answers Firecrawl's v2 search and scrape at `https://api.specstream.ai/firecrawl` in Firecrawl's JSON, and its Extract API scores 0.908 F1 on WCXB.

### How do I migrate from Firecrawl?

Change one base address and one key. Replace `https://api.firecrawl.dev` with `https://api.specstream.ai/firecrawl` and send a SpecStream key as the Bearer token. `POST /v2/search` and `POST /v2/scrape` keep their bodies.

### Is there a cheaper Firecrawl alternative?

SpecStream charges $0.005 a search and $0.0008 a page from a balance, and credit you top up never expires. Firecrawl's Standard plan is $99 a month for 100,000 credits, and a search takes 2 credits.

### Is there a free Firecrawl alternative?

New SpecStream accounts get $10 of credit with no card, which covers 2,000 searches or 12,500 pages. A page that gives no text is not charged.

### Does search with `scrapeOptions` return the whole page?

It returns up to about 3,500 characters per result: the text of the page closest to the query. For the whole page, call `/v2/scrape` for $0.0008.

### Does the Firecrawl SDK work with SpecStream?

The JavaScript SDK works with its API address set to `https://api.specstream.ai/firecrawl`. The Python SDK works with `api_url="https://api.specstream.ai"`, and so do the Firecrawl loaders of GPT Researcher, LangChain and LlamaIndex.

### Is there a Firecrawl alternative for Claude?

Yes. SpecStream's MCP server is at `https://api.specstream.ai/mcp`, and its `read_pages` tool reads up to 20 pages or documents a call at $0.80 per 1,000 pages.

## Sources

SpecStream wrote this page. The route's behavior is read from its code; each rival figure comes from that company's own page.

- [Firecrawl pricing](https://www.firecrawl.dev/pricing), read Nov 9, 2026
- [Exa pricing](https://exa.ai/docs/admin/pricing.md), read Nov 9, 2026
- [Tavily pricing](https://tavily.com/pricing), read Nov 9, 2026
- [Brave Search API](https://brave.com/search/api/), read Nov 9, 2026
- [Serper](https://serper.dev/), read Nov 9, 2026
- [SerpApi pricing](https://serpapi.com/pricing), read Nov 9, 2026
- [SpecStream benchmarks](https://specstream.ai/benchmarks), read Nov 10, 2026
- [SpecStream pricing](https://specstream.ai/pricing), read Nov 10, 2026
- [SpecStream for agents](https://specstream.ai/agents.md), read Nov 10, 2026
