diff --git a/CHANGELOG.md b/CHANGELOG.md index 847dada..493e4d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.61.1 — 2026-10-15 + +- **Removed per-endpoint credit prices from docstrings and docs again.** Baidu, ChatGPT, eBay image search, Google Shopping offers, LoopNet and the Apartments guide had picked up hard-coded "Costs N credits" lines, which the 2026-10-14 repricing made wrong. Prices are configured per endpoint by ScrapeBadger and served live from `GET /public/pricing`; see the per-endpoint docs at docs.scrapebadger.com. Free reference endpoints still say they are free. + ## 0.61.0 — 2026-10-14 - **`BlockedError` — why a web scrape was blocked.** A `web.scrape` whose every attempt hit an anti-bot wall (`422`, `error: "blocking_page_detected"`) now raises `BlockedError`, a subclass of `ValidationError`, so existing `except ValidationError` handlers still catch it. It exposes `block_kind` (`"antibot"`, `"captcha"`, `"rate_limit"`, `"ip_ban"`, `"geo_block"`, `"auth_wall"`, `"empty"` or `"other"`), `vendor` (the protection that served the wall, e.g. `"cloudflare"`, `"datadome"`, `"akamai"`, `"aws_waf"`), `captcha` (the CAPTCHA gating the page when `block_kind == "captcha"`: `system`, `version`, `gate`, `solvable`, `params` such as `sitekey`) and `data` (the scrape result returned with the block). Blocked requests are not charged. diff --git a/docs/apartments.md b/docs/apartments.md index 6a8003c..99ab00b 100644 --- a/docs/apartments.md +++ b/docs/apartments.md @@ -93,4 +93,5 @@ as schools. ## Cost -5 credits per search page and per property. +Each search page and each property is billed as one request. Current prices are +on the [Credits & Pricing](https://docs.scrapebadger.com/credits-and-pricing) page. diff --git a/pyproject.toml b/pyproject.toml index 490568d..7ce4ad5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "scrapebadger" -version = "0.61.0" +version = "0.61.1" description = "Official Python SDK for ScrapeBadger - Async web scraping APIs for Twitter and more" readme = "README.md" license = { text = "MIT" } diff --git a/src/scrapebadger/__init__.py b/src/scrapebadger/__init__.py index c17f90e..c30ab59 100644 --- a/src/scrapebadger/__init__.py +++ b/src/scrapebadger/__init__.py @@ -1336,7 +1336,7 @@ async def main(): ZestimateHistoryPoint as ZillowZestimateHistoryPoint, ) -__version__ = "0.61.0" +__version__ = "0.61.1" __all__ = [ # TikTok core models diff --git a/src/scrapebadger/baidu/client.py b/src/scrapebadger/baidu/client.py index 15b8f8c..e2df32a 100644 --- a/src/scrapebadger/baidu/client.py +++ b/src/scrapebadger/baidu/client.py @@ -80,8 +80,6 @@ async def search( ) -> SearchResponse: """Search baidu.com — the web SERP. - Costs 5 credits. - Args: query: Search keywords, e.g. ``"咖啡机"`` or ``"coffee machine"``. page: Result page, 1-76. Baidu's SERP stops serving past ~76 pages @@ -127,8 +125,6 @@ async def news( ) -> NewsResponse: """Search the Baidu news vertical. - Costs 5 credits. - Args: query: Search keywords, e.g. ``"人工智能"``. page: Result page, 1-76. @@ -155,8 +151,6 @@ async def news( async def images(self, query: str, *, page: int = 1) -> ImagesResponse: """Search Baidu images. - Costs 5 credits. - Args: query: Search keywords, e.g. ``"猫"``. page: Result page, 1-50. Baidu serves 30 images per page. @@ -183,8 +177,6 @@ async def images(self, query: str, *, page: int = 1) -> ImagesResponse: async def autocomplete(self, query: str) -> AutocompleteResponse: """Baidu search-box suggestions — the cheapest call in this API. - Costs 1 credit. - Args: query: Partial search term, e.g. ``"咖啡"`` or ``"coff"``. diff --git a/src/scrapebadger/chatgpt/ask.py b/src/scrapebadger/chatgpt/ask.py index 2660ae3..be39a48 100644 --- a/src/scrapebadger/chatgpt/ask.py +++ b/src/scrapebadger/chatgpt/ask.py @@ -47,7 +47,7 @@ async def ask( ) -> AskResponse: """Ask ChatGPT a question and get the answer with its sources. - Costs 20 credits. Typical latency is 20-25s ungrounded, 30-70s with web search. + Typical latency is 20-25s ungrounded, 30-70s with web search. Args: prompt: The prompt to send. Maximum 4096 characters. diff --git a/src/scrapebadger/chatgpt/brand.py b/src/scrapebadger/chatgpt/brand.py index fe2b5b0..0c35019 100644 --- a/src/scrapebadger/chatgpt/brand.py +++ b/src/scrapebadger/chatgpt/brand.py @@ -54,8 +54,6 @@ async def visibility( ) -> BrandVisibilityResponse: """Analyse how a brand shows up in ChatGPT's answer to a prompt. - Costs 25 credits. - Args: prompt: The prompt to send. Maximum 4096 characters. brand: The brand name to look for in the answer. diff --git a/src/scrapebadger/chatgpt/reference.py b/src/scrapebadger/chatgpt/reference.py index 874244f..aed3d9a 100644 --- a/src/scrapebadger/chatgpt/reference.py +++ b/src/scrapebadger/chatgpt/reference.py @@ -36,8 +36,6 @@ def __init__(self, client: BaseClient) -> None: async def models(self, *, country: str = "US") -> ModelsResponse: """Get the models chatgpt.com currently offers. - Costs 1 credit. - Args: country: ISO-3166 alpha-2 egress country. Defaults to "US". diff --git a/src/scrapebadger/ebay/search.py b/src/scrapebadger/ebay/search.py index 6fa13a0..1a6c17c 100644 --- a/src/scrapebadger/ebay/search.py +++ b/src/scrapebadger/ebay/search.py @@ -132,7 +132,7 @@ async def search_by_image( This is what the camera icon in eBay's search bar does: the picture is uploaded to eBay, which answers with a handle for it, and that handle is then searched like a keyword. The results are ordinary listings, so every - filter below behaves as it does on :meth:`search`. Costs 10 credits. + filter below behaves as it does on :meth:`search`. There is deliberately no ``sort_by``: eBay ignores sorting on a visual results page. diff --git a/src/scrapebadger/google/shopping.py b/src/scrapebadger/google/shopping.py index debd793..4afaa1d 100644 --- a/src/scrapebadger/google/shopping.py +++ b/src/scrapebadger/google/shopping.py @@ -141,7 +141,7 @@ async def offers( first) or ``catalog_id`` (Google Shopping ``catalogid`` — the ``catalog_id`` on ``shopping.search`` tiles or ``prds=catalogid:…`` in a Google Shopping URL; sellers read straight off Google's product - page). Costs 14 credits. + page). Args: barcode: Product barcode — a GTIN-8/UPC-A/EAN-13/GTIN-14. diff --git a/src/scrapebadger/loopnet/brokers.py b/src/scrapebadger/loopnet/brokers.py index f5992f1..ad061a7 100644 --- a/src/scrapebadger/loopnet/brokers.py +++ b/src/scrapebadger/loopnet/brokers.py @@ -39,7 +39,7 @@ async def get( *, market: str = "us", ) -> BrokerResponse: - """Get a LoopNet broker's profile and their listings. Costs 8 credits. + """Get a LoopNet broker's profile and their listings. Args: slug: The broker's URL slug (e.g. "jane-doe"). diff --git a/src/scrapebadger/loopnet/listings.py b/src/scrapebadger/loopnet/listings.py index 73cc683..445fe0b 100644 --- a/src/scrapebadger/loopnet/listings.py +++ b/src/scrapebadger/loopnet/listings.py @@ -33,7 +33,7 @@ def __init__(self, client: BaseClient) -> None: self._client = client async def get(self, listing_id: str, *, market: str = "us") -> ListingResponse: - """Get a single LoopNet listing's full detail. Costs 12 credits. + """Get a single LoopNet listing's full detail. Args: listing_id: The LoopNet listing id. diff --git a/src/scrapebadger/loopnet/search.py b/src/scrapebadger/loopnet/search.py index eb6d10b..66aa390 100644 --- a/src/scrapebadger/loopnet/search.py +++ b/src/scrapebadger/loopnet/search.py @@ -48,7 +48,7 @@ async def search( min_size: int | None = None, max_size: int | None = None, ) -> SearchResponse: - """Search LoopNet for commercial listings. Costs 10 credits. + """Search LoopNet for commercial listings. Args: location: City/state ("Houston, TX"), ZIP, state code, or "usa" (required). diff --git a/src/scrapebadger/vinted/search.py b/src/scrapebadger/vinted/search.py index b88fd0b..3662114 100644 --- a/src/scrapebadger/vinted/search.py +++ b/src/scrapebadger/vinted/search.py @@ -91,7 +91,7 @@ async def search( no native country filter, so ScrapeBadger applies this filter. When set, each returned item gains a ``seller_country_code`` and the response gains a top-level ``seller_country`` echo. - Billing: a search is a flat 5 credits whatever filters you + Billing: a search is one flat price whatever filters you pass; seller lookups are not billed on top. Returns: diff --git a/uv.lock b/uv.lock index 85d2cde..1e309ab 100644 --- a/uv.lock +++ b/uv.lock @@ -930,7 +930,7 @@ wheels = [ [[package]] name = "scrapebadger" -version = "0.61.0" +version = "0.61.1" source = { editable = "." } dependencies = [ { name = "httpx" },