Migrating from ScrapingBee
ScrapingBee is a general-purpose scraper; APITube is a news index. This guide is narrower than the others in this section because the honest answer for many ScrapingBee calls is "keep scraping that one".
Two things convert: the Google Search API with search_type=news, and HTML API scrapes of news articles from publishers APITube indexes. Everything else stays where it is.
Why teams move the news half
| ScrapingBee | APITube | |
|---|---|---|
| Article text | One fetch per article, then your extraction rules | body and body_html in the same response |
| Per request | One page | Up to 250 articles |
| Cost model | Credits per request: 1 without JS, 5 with, 10–25 premium proxy, 75 stealth, 15 for a Google search | No per-request credit |
| Discovery | RSS parsing, sitemap crawling, or SERP scraping | The query is the discovery |
| Extraction | Per-publisher selectors that break on redesigns | Structured fields |
| Enrichment | Yours to build | Entities, sentiment, IPTC categories, topics, industries, readability, publisher bias |
Credit costs are from ScrapingBee's knowledge base. News sites are the case that pushes you up that table — paywalls, consent walls and lazy-loaded bodies make render_js and often premium_proxy non-optional.
For 100 articles with text: roughly 101 ScrapingBee requests and 515–2 530 credits, against one APITube request. Verified on 27 July 2026: title=tesla&per_page=250 returned 250 articles, every one with a non-empty body, averaging 4 818 characters.
Your first request
# ScrapingBee
curl "https://app.scrapingbee.com/api/v1/store/google?search=tesla&search_type=news&country_code=us" \
-H "Authorization: Bearer YOUR_KEY"# APITube
curl "https://api.apitube.io/v1/news/everything?title=tesla&source.country.code=us" \
-H "X-API-Key: YOUR_API_KEY"Parameter mapping
| ScrapingBee | APITube | Note |
|---|---|---|
search | title, query, source.domain, published_at.* | Google operators split into separate parameters |
search_type=news | — | Endpoint choice. The other seven values have no equivalent |
country_code | source.country.code | Proxy country → publisher country. uk must become gb |
extra_params[hl] | language.code | Two letters only; en-US returns 400 ER0061 |
extra_params[gl] | source.country.code | Same caveat as country_code |
extra_params[num] | per_page | Max 250 |
extra_params[start] | page | Offset → page number |
extra_params[tbs] | published_at.start / .end | Write the bound explicitly |
url | — | No URL lookup exists — see below |
extract_rules | title, body, published_at, author.name, image | The fields are already there |
render_js, premium_proxy, wait*, block_* | — | No fetch to make succeed |
js_scenario, screenshot*, cookies, session_id | — | Keep ScrapingBee |
Operators inside search: site: → source.domain, -site: → ignore.source.domain, when:7d → published_at.start=NOW-7d, -term → ignore.title, intitle: becomes free (APITube only searches headlines). inurl: has no equivalent.
The trap that matters most
There is no URL lookup, and the obvious parameter names fail silently.
curl "https://api.apitube.io/v1/news/count?api_key=YOUR_API_KEY&href=https%3A%2F%2Fwww.bbc.co.uk%2Fnews%2Farticles%2Fc8dng1v72lno"
# {"count":3050326333} ← the entire indexhref=, url=, article.href= and link= all return 200 with the whole index and articles unrelated to the URL. Coming from a scraper, "here is a URL, give me the page" is the first thing you will try. Query by topic, entity or publisher instead.
What stays a scrape
- Sites that are not news publishers — competitor pages, government portals, forums, e-commerce
- Anything behind a login (
cookies,session_id) - Anything interactive (
js_scenario— consent walls, "load more", pagination) - Screenshots
- Arbitrary DOM extraction against structure APITube does not model
- Fetching one specific URL
The realistic outcome is a smaller ScrapingBee bill, not a cancelled one. The migration kit has the detailed boundary in reference/what-you-keep-scraping.md.
Check your domains first
curl "https://api.apitube.io/v1/news/count?api_key=YOUR_API_KEY&source.domain=example.com"Three outcomes, and only one is an error: a count, {"count": 0} with a 200 (indexed but empty), or 400 ER0214 (not in the source index). A script that checks only HTTP status will treat the middle case as success. Coverage is uneven — on 27 July 2026 theguardian.com, apnews.com, techcrunch.com and bbc.co.uk returned four-figure counts while reuters.com and cnn.com returned zero.
Other things that will bite
Search is headlines-only. No body-text parameter. Filter on organization.name instead of a keyword, or filter the returned body locally.
NOW-30m means thirty months. APITube reads m as months. NOW-1h, NOW-7d and NOW-1y behave as expected; there is no minutes unit.
Wildcards return everything. title=immuni* gives 200 and the whole index. Expand into query=title:(immunity OR immunization OR immunology).
Unknown parameters are ignored. A forwarded search= or render_js= produces a successful-looking response with the query unfiltered.
What you gain
The article text arrives with the search result, so the fetch-and-extract stage disappears — with its retries, its per-publisher selectors and its credit arithmetic. Plus named entities with per-entity sentiment, sentiment on title and body separately, IPTC MediaTopics alongside topic and industry axes, publisher political bias and Open Page Rank, readability scores, deduplication via is_duplicate and story.id, and export to eight formats.
Next steps
- scrapingbee-apitube-migration-kit — both scenarios mapped, the honest boundary of what stays a scrape, a drop-in shim for Node.js and Python (73 tests, byte-identical output between the two), and an AI prompt that refuses to convert what cannot be converted
- Parameters reference
- Common migration issues