Bright Data compatible
Keep the /request call, change the host.
Bright Data's Web Unlocker and SERP API both answer POST https://api.brightdata.com/request, at $1.5 per 1,000 requests on pay as you go. SpecStream answers the same call at https://api.specstream.ai/brightdata/request: $1 per 1,000 searches and $0.80 per 1,000 pages.
In code that posts to that address, the switch is one line and a SpecStream key as the Bearer token. @brightdata/sdk holds the address in a constant, so you point its endpoint table at SpecStream, and scrapeUrl and search.google run as before.
The SpecStream Search API scores 97.9 F-score on SimpleQA Verified and the Extract API 0.908 F1 on WCXB. Credit you buy never expires, and a new account gets $10 of credit, no card.
New accounts get $10 of credit, no card. It covers 10,000 searches or 12,500 pages.
Bright Data to SpecStream, field by field, from @brightdata/sdk 1.2.0 and Bright Data's docs on Nov 13, 2026
| SpecStream | Bright Data | |
|---|---|---|
| Address | POST https://api.specstream.ai/brightdata/request | POST https://api.brightdata.com/request |
| The key | A SpecStream key as Authorization: Bearer, as the SDK sends it | A Bright Data API token as Authorization: Bearer, from BRIGHTDATA_API_TOKEN in the SDK |
| Read a page | A body with any page url is one Extract API read. data_format markdown returns the page as markdown | Web Unlocker: {"zone":"YOUR_ZONE_NAME","url":"https://example.com","format":"raw"}. Returns clean HTML or JSON |
| Search | A body whose url is a Google, Bing or Yandex results address is one search of the live web | SERP API: the same call with a results address such as https://www.google.com/search?q=pizza&hl=en&gl=us |
| Parsed results | brd_json=1 returns general, input, organic[] with link, display_link, title, description, rank and global_rank, and pagination | brd_json=1 in the results address returns the page as parsed JSON |
| Reply form | format raw returns the answer itself, json wraps it as status_code, headers and body | format is raw by default or json in the SDK |
| Zones | Every zone name is accepted, the zone list answers and a zone creation succeeds, so autoCreateZones passes. Free | The SDK creates sdk_unlocker and sdk_serp in your account when they are missing |
| SDK calls answered | scrapeUrl, search.google, search.bing, search.yandex, each with one input or a list, and listZones | Those, and the dataset, crawl, discover, Scraper Studio and Browser API calls of the SDK |
| Price | $1 per 1,000 searches of up to 10 results, $0.80 per 1,000 pages. $1.5 buys 1,500 searches or 1,875 pages | $1.5 per 1,000 requests on pay as you go, for SERP API and for Web Unlocker |
| Failed requests | Not charged. A page with no main text is not charged, and a search with no results is not charged | Failed requests are not billed. On a SERP zone with custom headers or cookies, all requests are billed |
| Free to start | $10 of credit, no card, which never expires | 5,000 free credits per month, about $7.50, which do not roll over |
The Bright Data request, on SpecStream
The one-line change, in code that posts to /request
If your code sends the request itself, with curl, requests, fetch or axios, change the host and the token and leave the body alone. This is the SERP call from Bright Data's docs, on SpecStream:
curl -X POST https://api.specstream.ai/brightdata/request \
-H "Authorization: Bearer $SPECSTREAM_KEY" -H "Content-Type: application/json" \
-d '{"zone": "sdk_serp", "url": "https://www.google.com/search?q=pizza&hl=en&gl=us&brd_json=1", "format": "raw"}'And the Web Unlocker call, which returns the page. Add "data_format": "markdown" for markdown.
curl -X POST https://api.specstream.ai/brightdata/request \
-H "Authorization: Bearer $SPECSTREAM_KEY" -H "Content-Type: application/json" \
-d '{"zone": "sdk_unlocker", "url": "https://en.wikipedia.org/wiki/Web_scraping", "format": "raw"}'@brightdata/sdk: point its endpoint table at SpecStream
@brightdata/sdk 1.2.0 has no base address option: utils/constants.cjs holds https://api.brightdata.com and builds every endpoint from it. Replace that host in the endpoint table once, before you create the client. The rest of your code stays as it is. SpecStream's tests run Bright Data's own client this way.
const path = require("path");
const { bdclient } = require("@brightdata/sdk");
// The client takes no base address, so point its endpoint table at SpecStream first.
const constants = require(path.join(path.dirname(require.resolve("@brightdata/sdk")), "utils/constants.cjs"));
for (const [name, value] of Object.entries(constants.API_ENDPOINT)) {
constants.API_ENDPOINT[name] = value.replace("https://api.brightdata.com", "https://api.specstream.ai/brightdata");
}
(async () => {
const client = new bdclient({ apiKey: process.env.SPECSTREAM_API_KEY });
const markdown = await client.scrapeUrl("https://en.wikipedia.org/wiki/Web_scraping", { dataFormat: "markdown" });
const results = JSON.parse(await client.search.google("pizza restaurants", { country: "us" }));
console.log(markdown.slice(0, 200), results.organic[0].link);
await client.close();
})();The client lists zones and creates a missing one before its first call. SpecStream answers both, so autoCreateZones can stay on. This works where the SDK is loaded with require.
What each field does here
url: a Google address with path /search, a Bing address with /search or /news/search, or a Yandex address with /search is a search. Any other address is a page read. zone is accepted and changes nothing, since one route serves both.
Search fields are read from the results address as Bright Data's client writes them: q, start, hl, gl, safe, tbs=qdr: and tbm=nws for Google, q, count, first, mkt and cc for Bing, text, numdoc, p and lang for Yandex. country in the body sets the country when the address names none.
Without brd_json=1, a search returns a plain HTML page of the results, each a link and its snippet, and with data_format markdown a markdown list. The parsed reply carries pagination.next_page_link when more results exist.
Refused with a 400: data_format screenshot, a method other than GET, and image or video searches. A page SpecStream cannot read answers 502, and a missing page 404. A busy call gets 429 with Retry-After and is not charged.
One price for a search and one for a page
A search of up to 10 results is $0.001. Each started block of 10 more results in the same call adds $0.0012, up to 100 results. A page is one Extract API page at $0.0008, the same for every site. There is no plan and no zone to set up, and each charged reply carries the balance left in X-Balance-Cents.
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 page.
You decide what is kept, on each key
Create a 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, so a job that loops stops at the cap you set.
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}'For the SDK's dataset calls, ask for the rows
The SDK's platform scrapers and dataset calls go to Bright Data's /datasets addresses, which this route does not answer. On SpecStream that job is Deep Search: a request in plain words returns every match on the live web as rows, at 5¢, 15¢ or $1 a row, with the most a run can cost quoted before it starts. Bright Data's rates for each product are on Bright Data pricing.
What else Bright Data users price
SerpApi
Search results as JSON on monthly plans: Starter is $25 a month for 1,000 searches, and cached, errored and failed searches are not counted. SpecStream answers 1,000 searches for $1, and SerpApi's own call too: see the SerpApi migration guide.
Firecrawl
Search and scrape billed in credits: 2 credits per 10 search results, and Hobby at $19 a month for 5,000 credits. On SpecStream a search is $0.001 and a page $0.0008 with no plan to buy, and Firecrawl's calls work on our address: see the Firecrawl migration guide.
ScraperAPI
A page API on monthly plans: Hobby is $49 a month for 100,000 API credits. SpecStream reads 100,000 pages for $80 with no monthly plan, and answers ScraperAPI's call: see the ScraperAPI migration guide.
Tavily
A search API billed in credits at $0.008 a credit on pay as you go. On SpecStream a search is $0.001, and Tavily's client runs on our address: see the Tavily migration guide.
How SpecStream scores
The same numbers as the benchmarks page, from the official tasks and scorers.
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 10,000 searches or 12,500 pages.
2. In code that posts to Bright Data, set the address to https://api.specstream.ai/brightdata/request and send the SpecStream key as the Bearer token. In Python:
import requests
URL = "https://api.specstream.ai/brightdata/request" # was https://api.brightdata.com/request
reply = requests.post(
URL,
headers={"Authorization": f"Bearer {SPECSTREAM_KEY}"},
json={"zone": "sdk_serp", "url": "https://www.google.com/search?q=pizza&hl=en&gl=us&brd_json=1", "format": "raw"},
timeout=60,
)
reply.raise_for_status()
for item in reply.json()["organic"]:
print(item["rank"], item["title"], item["link"])3. With @brightdata/sdk, replace the host in its endpoint table before you create the client, and pass the SpecStream key as apiKey:
const path = require("path");
const { bdclient } = require("@brightdata/sdk");
// The client takes no base address, so point its endpoint table at SpecStream first.
const constants = require(path.join(path.dirname(require.resolve("@brightdata/sdk")), "utils/constants.cjs"));
for (const [name, value] of Object.entries(constants.API_ENDPOINT)) {
constants.API_ENDPOINT[name] = value.replace("https://api.brightdata.com", "https://api.specstream.ai/brightdata");
}
(async () => {
const client = new bdclient({ apiKey: process.env.SPECSTREAM_API_KEY });
const markdown = await client.scrapeUrl("https://en.wikipedia.org/wiki/Web_scraping", { dataFormat: "markdown" });
const results = JSON.parse(await client.search.google("pizza restaurants", { country: "us" }));
console.log(markdown.slice(0, 200), results.organic[0].link);
await client.close();
})();4. Read 429 as a call to send again after Retry-After. It is not charged. The SDK already retries a 429 by itself.
5. Keep your Bright Data token for the dataset, crawl and browser calls until you move those jobs to rows. Every drop-in address is listed on migrate.
Frequently asked questions
Something we didn't answer? Talk to a human
Can I change the base URL of @brightdata/sdk?
https://api.brightdata.com with https://api.specstream.ai/brightdata in its API_ENDPOINT table before you create the client, and searches cost $1 per 1,000.What is a Bright Data compatible API?
POST /request with Bright Data's body: zone, url, format and data_format. SpecStream does at https://api.specstream.ai/brightdata/request, at $1 per 1,000 searches and $0.80 per 1,000 pages.How much does the Bright Data SERP API cost?
How much does Bright Data Web Unlocker cost?
Do I need to create zones on SpecStream?
zone name is accepted, and the zone list and zone creation calls the SDK makes are answered and cost nothing.Which Bright Data SDK calls work on SpecStream?
scrapeUrl, search.google, search.bing and search.yandex, with one input or a list, plus listZones. Dataset, crawl, discover, Scraper Studio and Browser API calls stay on Bright Data's addresses.Sources
SpecStream wrote this page. Each Bright Data figure comes from Bright Data's own pages and its SDK's published code, and each other provider's figure from that company's own page. The route's behavior comes from its code and its tests with Bright Data's own client.
- @brightdata/sdk 1.2.0, constantsunpkg.com/@brightdata/[email protected]/dist/cjs/utils/constants.cjs, read Nov 13, 2026
- @brightdata/sdk 1.2.0, READMEunpkg.com/@brightdata/[email protected]/README.md, read Nov 13, 2026
- Bright Data SERP API pricingbrightdata.com/pricing/serp, read Nov 13, 2026
- Bright Data Web Unlocker pricingbrightdata.com/pricing/web-unlocker, read Nov 13, 2026
- Bright Data free tierdocs.brightdata.com/general/account/billing-and-pricing/free-tier, read Nov 13, 2026
- Bright Data Web Unlocker introductiondocs.brightdata.com/products/web-unlocker/introduction, read Nov 13, 2026
- Bright Data SERP API introductiondocs.brightdata.com/scraping-automation/serp-api/introduction, read Nov 13, 2026
- Bright Data SERP API pricing and billingdocs.brightdata.com/products/serp-api/pricing-and-billing, read Nov 13, 2026
- SerpApi pricingserpapi.com/pricing, read Nov 13, 2026
- Firecrawl pricingfirecrawl.dev/pricing, read Nov 13, 2026
- ScraperAPI pricingscraperapi.com/pricing/, read Nov 13, 2026
- Tavily API creditsdocs.tavily.com/documentation/api-credits.md, read Nov 13, 2026
- SpecStream benchmarksspecstream.ai/benchmarks, read Nov 13, 2026
- SpecStream pricingspecstream.ai/pricing, read Nov 13, 2026
- SpecStream for agentsspecstream.ai/agents.md, read Nov 13, 2026




