<!-- twin of https://specstream.ai/migrate/zenrows -->
# ZenRows compatible: change the address, keep the client

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

ZenRows plans start at $19 a month for 45,000 credits, a JavaScript-rendered request always costs 5 credits, and plan credits expire at every renewal. SpecStream answers the same `GET /v1/` call at one price: $0.80 per 1,000 pages.

The switch is one line: `https://api.specstream.ai/zenrows/v1/` in place of `https://api.zenrows.com/v1/`, and a SpecStream key as `apikey`. In the Python SDK it is `base_url` or `ZENROWS_SCRAPER_BASE_URL`.

The SpecStream Extract API scores 0.908 F1 on WCXB. A failed page costs nothing, credit you buy never expires, and a new account gets $10 of credit, no card.

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

## ZenRows to SpecStream, parameter by parameter and field by field

| | SpecStream | ZenRows |
|---|---|---|
| Address | `GET https://api.specstream.ai/zenrows/v1/?apikey=&url=` | `GET https://api.zenrows.com/v1/?apikey=&url=` |
| The key | A SpecStream key as `apikey`, as the SDK sends it | The `apikey` query parameter |
| Output | The page's HTML, markdown or plain text with `response_type`, JSON with `json_response`, and `links` and `emails` with `outputs` | The page's HTML by default, changed by `response_type`, `json_response` and other options |
| Errors | ZenRows' own codes: `404` `RESP002` for a missing page, `422` `RESP001` for a host that does not resolve, `400` `REQS004` with no `url`, `401` `AUTH002` for a wrong key. A busy call gets `429` with `Retry-After` and is not charged | `402` `AUTH004` when the key has spent its credit allowance, `429` `AUTH006` when the concurrency limit is reached |
| Failed requests | Not charged, and a page with no main text is not charged | Never charged. `404` and `410` count as successful results |
| Price | $0.80 per 1,000 pages, the same for every page. $19 reads 23,750 pages | Build B1 $19 a month for 45,000 credits. JavaScript rendering costs 5 credits, a protected request 25 |
| Credit | Credit you buy never expires | Unused plan credits expire at every renewal |
| Free to start | $10 of credit, no card, which covers 12,500 pages | Free plan: 5,000 credits a month |

## The ZenRows reference, on SpecStream

### The call, before and after

```
# Before
curl -G https://api.zenrows.com/v1/ \
  --data-urlencode "apikey=$ZENROWS_API_KEY" \
  --data-urlencode "url=https://en.wikipedia.org/wiki/Web_scraping"

# After
curl -G https://api.specstream.ai/zenrows/v1/ \
  --data-urlencode "apikey=$SPECSTREAM_API_KEY" \
  --data-urlencode "url=https://en.wikipedia.org/wiki/Web_scraping"
```

With ZenRows' Python SDK, `zenrows` 1.13.0, the change is the constructor: `client = ZenRowsClient(SPECSTREAM_KEY, base_url="https://api.specstream.ai/zenrows/v1/")`. Setting `ZENROWS_SCRAPER_BASE_URL` to the same address works the same way. `client.get(url)` then runs as before.

### What the route reads, and what it refuses

Read and applied: `url`, `apikey`, `response_type` with `markdown` or `plaintext`, `json_response`, and `outputs` with `links` and `emails`. A page the site does not have comes back as ZenRows' `404` `RESP002`.

Refused, in ZenRows' own error body: no `url` gets `400` `REQS004`, `mode=auto` together with `js_render` gets `400` `REQS004`, a wrong key gets `401` `AUTH002`, and a host that does not resolve gets `422` `RESP001`. Every parameter was measured on production on Nov 10, 2026, and the full [pass table](https://specstream.ai/specstream/dialects/zenrows.md) lists each one and its result.

### Every field that comes back

By default the body is the page itself. `json_response=true` returns `html` with the page, and `outputs` returns `links` and `emails`. A refused call carries ZenRows' `code`, `status`, `title`, `detail`, `type` and `instance`.

The route does not send the `X-Request-Id`, `X-Request-Cost`, `Zr-Final-Url` and `Concurrency-*` headers, nor `xhr` in the JSON form, nor `headings` and `images` from `outputs`.

### One price a page, and credit that stays

On ZenRows a JavaScript-rendered request costs 5 credits, a protected one 25, and unused plan credits expire at every renewal. On SpecStream every page read costs $0.0008, which is $0.80 per 1,000, a failed page is not charged, and a busy call gets `429` with `Retry-After` and charges nothing. Credit you buy never expires.

### Scored on the official benchmarks

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

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

Create the key with `zero_retention` and a call made with it keeps no request text and no answer after the reply. `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}'
```

### Pages, search and rows on one key

The same key reads up to 20 pages or documents a call with the [Extract API](https://specstream.ai/extract-api?utm_source=alternatives&utm_campaign=migrate-zenrows), searches the web at $5 per 1,000 searches, and runs [Deep Search](https://specstream.ai/deep-search?utm_source=alternatives&utm_campaign=migrate-zenrows), which 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. The full comparison is on the [ZenRows alternative](https://specstream.ai/alternatives/zenrows?utm_source=alternatives&utm_campaign=migrate-zenrows) page.

## What else ZenRows users price

### ScrapingBee

A page API from $19 a month for 75,000 credits, where a default call with JavaScript costs 5 credits and credits don't roll over. SpecStream answers ScrapingBee's call at `https://api.specstream.ai/scrapingbee/api/v1/` too, at $0.80 per 1,000 pages.

### ScraperAPI

A page API on monthly plans: Hobby is $49 a month for 100,000 API credits, and the balance resets when the subscription renews. SpecStream answers ScraperAPI's call at `https://api.specstream.ai/scraperapi` too, at $0.80 per 1,000 pages.

### Scrapfly

A page API from $30 a month for 200,000 credits, where browser rendering adds 5 credits a request. SpecStream answers Scrapfly's `/scrape` call too, and its credit never expires.

### Firecrawl

Scrape, search and crawl in credits: Hobby is $19 a month for 5,000 credits. SpecStream answers Firecrawl's v2 calls at `https://api.specstream.ai/firecrawl`, and $19 reads 23,750 pages.

## How to migrate, step by step

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

2. Set the address to `https://api.specstream.ai/zenrows/v1/` where your code has `https://api.zenrows.com/v1/`, and send the SpecStream key as `apikey`. In Python:

```
import requests

URL = "https://api.specstream.ai/zenrows/v1/"  # was https://api.zenrows.com/v1/

reply = requests.get(
    URL,
    params={"apikey": SPECSTREAM_KEY, "url": "https://en.wikipedia.org/wiki/Web_scraping", "response_type": "markdown"},
    timeout=60,
)
reply.raise_for_status()
print(reply.text[:500])
```

3. In JavaScript:

```
const url = new URL("https://api.specstream.ai/zenrows/v1/");
url.search = new URLSearchParams({ apikey: process.env.SPECSTREAM_KEY, url: "https://en.wikipedia.org/wiki/Web_scraping", outputs: "links,emails" });
const data = await (await fetch(url)).json();
console.log(data.links.length, data.emails);
```

4. Read `429` as a call to send again after `Retry-After`. It is not charged.

## Frequently asked questions

### Is there a ZenRows compatible API?

Yes. SpecStream answers ZenRows' `GET /v1/` at `https://api.specstream.ai/zenrows/v1/` with ZenRows' reply and error codes, as measured on production on Nov 10, 2026. A page costs $0.0008.

### How do I migrate from ZenRows?

Change one address: `https://api.zenrows.com/v1/` becomes `https://api.specstream.ai/zenrows/v1/`, and a SpecStream key goes in `apikey`. `url`, `response_type`, `json_response` and `outputs` keep their meaning.

### How much does ZenRows cost?

Plans start at $19 a month for 45,000 credits, with a free plan of 5,000 credits a month. A JavaScript-rendered request costs 5 credits and a protected one 25. SpecStream costs $0.80 per 1,000 pages with no plan.

### Does the ZenRows Python SDK work with SpecStream?

Yes. `zenrows` 1.13.0 works with `base_url="https://api.specstream.ai/zenrows/v1/"` or with `ZENROWS_SCRAPER_BASE_URL` set to that address, as tested on production on Nov 10, 2026.

### Do ZenRows credits roll over?

No. ZenRows says unused plan credits expire at every renewal. SpecStream credit you buy never expires.

### Which ZenRows fields does SpecStream not return?

The `X-Request-Id`, `X-Request-Cost`, `Zr-Final-Url` and `Concurrency-*` headers, `xhr` in the JSON form, and `headings` and `images` from `outputs`. The page, `html`, `links` and `emails` come back.

## Sources

SpecStream wrote this page. Each ZenRows figure comes from ZenRows' own pages, and each other provider's figure from that company's own page. The route's behavior comes from its code and the pass table measured on production.

- [ZenRows pricing](https://docs.zenrows.com/first-steps/pricing.md), read Nov 10, 2026
- [ZenRows authentication](https://docs.zenrows.com/authentication.md), read Nov 10, 2026
- [ZenRows error codes](https://docs.zenrows.com/api-error-codes.md), read Nov 10, 2026
- [SpecStream ZenRows pass table](https://specstream.ai/specstream/dialects/zenrows.md), read Nov 10, 2026
- [ScrapingBee pricing](https://www.scrapingbee.com/pricing/), read Nov 10, 2026
- [ScraperAPI pricing](https://www.scraperapi.com/pricing/), read Nov 10, 2026
- [Scrapfly pricing](https://scrapfly.io/pricing), read Nov 10, 2026
- [Firecrawl pricing](https://www.firecrawl.dev/pricing), read Nov 10, 2026
- [Scrapfly billing](https://scrapfly.io/docs/scrape-api/billing), read Nov 10, 2026
- [ScrapingBee documentation](https://www.scrapingbee.com/documentation/), read Nov 10, 2026
- [SpecStream benchmarks](https://specstream.ai/benchmarks), read Nov 10, 2026
- [SpecStream for agents](https://specstream.ai/agents.md), read Nov 10, 2026
