# Airbnb Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/airbnb/overview Scrape Airbnb stays search, full listing detail, 12-month availability calendars, paginated reviews, and experiences — worldwide, with structured JSON responses. ## Scraper API for Airbnb Search stays by place name or map bounding box, pull a listing's full detail, read a 12-month availability and pricing calendar, page through guest reviews, and search Airbnb **Experiences** — all from **Airbnb** worldwide. ScrapeBadger handles authentication, rotating proxies, anti-bot evasion, and parsing automatically — no upstream API key required. ## Key Features Free-text [`location`](/api-reference/endpoint/airbnb/search) or a precise map bounding box, with dates, guest counts, price, bedrooms, beds, bathrooms, and room-type filters. Description, room type, capacity, GPS, address, rating breakdown across six categories, amenities, house rules, cancellation policy, host profile, and every photo. Day-by-day availability, check-in / check-out eligibility, min and max nights, and nightly price for up to twelve months ahead. Full review text with ratings, language, reviewer profile, host responses, and photos — sorted by recency or rating. Search Airbnb Experiences by location and fetch full experience detail — duration, highlights, host, price, and GPS. First-class support via the ScrapeBadger Node.js and Python SDKs. Coverage is global — anywhere Airbnb lists stays or experiences is reachable. Every endpoint accepts `currency` and `locale`, defaulting to `USD` and `en`, so you can request prices and text in the market's own currency and language without changing anything else. ## Coverage & Defaults | Parameter | Default | Notes | | - | - | - | | `currency` | `USD` | Any Airbnb-supported currency, e.g. `EUR`, `GBP`, `JPY`. | | `locale` | `en` | Any Airbnb-supported locale, e.g. `fr`, `es`, `it`, `de`. | | Geography | Worldwide | Free-text `location` is geocoded server-side; a map bounding box is also accepted. | Start from [`/search`](/api-reference/endpoint/airbnb/search) to get `room_id` values, then reuse the same id on [`/listings/{room_id}`](/api-reference/endpoint/airbnb/get-listing), [`/listings/{room_id}/calendar`](/api-reference/endpoint/airbnb/get-calendar), and [`/listings/{room_id}/reviews`](/api-reference/endpoint/airbnb/get-reviews). ## Quick Start ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/airbnb/search?" + new URLSearchParams({ location: "Paris, France", check_in: "2026-09-12", check_out: "2026-09-15", adults: "2", price_max: "250", room_type: "Entire home/apt", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); console.log(data.count, "listings"); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/airbnb/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "location": "Paris, France", "check_in": "2026-09-12", "check_out": "2026-09-15", "adults": 2, "price_max": 250, "room_type": "Entire home/apt", }, ) data = res.json() print(data["count"], "listings") ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/airbnb/search?location=Paris%2C%20France&check_in=2026-09-12&check_out=2026-09-15&adults=2&price_max=250" \ -H "X-API-Key: YOUR_API_KEY" ``` ## Endpoints | Endpoint | Method | Description | | - | - | - | | [`/v1/airbnb/search`](/api-reference/endpoint/airbnb/search) | GET | Search stays by place or map bounding box | | [`/v1/airbnb/listings/{room_id}`](/api-reference/endpoint/airbnb/get-listing) | GET | Full detail for a single listing | | [`/v1/airbnb/listings/{room_id}/calendar`](/api-reference/endpoint/airbnb/get-calendar) | GET | Up to 12 months of availability and pricing | | [`/v1/airbnb/listings/{room_id}/reviews`](/api-reference/endpoint/airbnb/get-reviews) | GET | Paginated guest reviews | | [`/v1/airbnb/experiences`](/api-reference/endpoint/airbnb/search-experiences) | GET | Search Airbnb Experiences by location | | [`/v1/airbnb/experiences/{experience_id}`](/api-reference/endpoint/airbnb/get-experience) | GET | Full detail for a single experience | ## Credit Costs | Endpoint | Cost | | - | - | | Search stays | 5 credits | | Get listing detail | 5 credits | | Get calendar | 5 credits | | Get reviews | 5 credits | | Search experiences | 5 credits | | Get experience detail | 5 credits | | Health check | 0 credits | | Failed requests | 0 credits | ## Authentication All requests require your API key in the `X-API-Key` header: ```bash theme={null} curl "https://scrapebadger.com/v1/airbnb/search?location=Paris%2C%20France" \ -H "X-API-Key: YOUR_API_KEY" ``` Credits are charged per request (see the table above) and reported on the `X-Credits-Used` response header. ## Anti-Bot & Proxies Airbnb protects its inventory with IP-reputation scoring, TLS/HTTP fingerprinting, and session-bound API tokens. ScrapeBadger clears these automatically using rotating proxies, browser fingerprint rotation, and freshly minted sessions. You never manage proxies, sessions, or CAPTCHAs, and you never need an upstream API key. ## Next Steps Full API reference for searching Airbnb stays Retrieve a listing's complete detail by its `room_id` *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Airbnb. "Airbnb" is a trademark of Airbnb, Inc., used here only to describe the platform this scraper is designed to work with.* # Amazon Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/amazon/overview Scrape Amazon products, offers, reviews, listings, and seller data across 20 marketplaces with structured JSON responses. ## Scraper API for Amazon Search products, fetch full product detail, list offers and reviews, pull bestsellers, new releases, and deals, and retrieve seller storefronts from Amazon — the world's largest online marketplace. The API handles authentication, anti-bot bypass, and marketplace routing automatically. ## Key Features Access all major Amazon marketplaces including US, UK, DE, FR, IT, ES, JP, CA, IN, AU, and more. Automatic AWS WAF bypass via Chrome TLS impersonation, fresh residential sessions, and origin warmup. Variants, badges, buybox, best-seller ranks, A+ content, specs, and frequently-bought-together. Clean JSON responses with normalized prices, ratings, reviews, offers, and seller feedback. Requests are routed through residential proxies matching the target marketplace for accurate pricing. First-class support via the ScrapeBadger Node.js and Python SDKs. ## Supported Marketplaces Amazon operates across 20 country domains. Use the `domain` query parameter to target a specific one. | Market | Domain | Market | Domain | | - | - | - | - | | :us: `com` | amazon.com | :gb: `co.uk` | amazon.co.uk | | :de: `de` | amazon.de | :fr: `fr` | amazon.fr | | :it: `it` | amazon.it | :es: `es` | amazon.es | | :netherlands: `nl` | amazon.nl | :sweden: `se` | amazon.se | | :poland: `pl` | amazon.pl | :canada: `ca` | amazon.ca | | :mexico: `com.mx` | amazon.com.mx | :brazil: `com.br` | amazon.com.br | | :japan: `co.jp` | amazon.co.jp | :india: `in` | amazon.in | | :australia: `com.au` | amazon.com.au | :singapore: `sg` | amazon.sg | | :united\_arab\_emirates: `ae` | amazon.ae | :saudi\_arabia: `sa` | amazon.sa | | :tr: `com.tr` | amazon.com.tr | :egypt: `eg` | amazon.eg | If no `domain` is specified, it defaults to `com`. Use the [`/v1/amazon/markets`](/api-reference/endpoint/amazon/list-markets) endpoint to get the full list (with currency and locale) programmatically. ## Quick Start ```javascript Node.js theme={null} import ScrapeBadger from "scrapebadger"; const client = new ScrapeBadger({ apiKey: "YOUR_API_KEY" }); const results = await client.amazon.search({ query: "wireless earbuds", domain: "com", page: 1, }); console.log(results.results); ``` ```python Python theme={null} from scrapebadger import ScrapeBadger client = ScrapeBadger(api_key="YOUR_API_KEY") results = client.amazon.search( query="wireless earbuds", domain="com", page=1, ) print(results.results) ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/amazon/search?query=wireless+earbuds&domain=com&page=1" \ -H "x-api-key: YOUR_API_KEY" ``` ## Endpoints | Endpoint | Method | Description | | - | - | - | | [`/v1/amazon/search`](/api-reference/endpoint/amazon/search-products) | GET | Search the Amazon catalog with filters and sorting | | [`/v1/amazon/autocomplete`](/api-reference/endpoint/amazon/autocomplete) | GET | Keyword autocomplete suggestions | | [`/v1/amazon/products/{asin}`](/api-reference/endpoint/amazon/get-product) | GET | Full product detail by ASIN | | [`/v1/amazon/products/{asin}/offers`](/api-reference/endpoint/amazon/get-offers) | GET | All seller offers, including the Buy Box winner | | [`/v1/amazon/products/{asin}/reviews`](/api-reference/endpoint/amazon/get-reviews) | GET | Customer reviews with filters | | [`/v1/amazon/bestsellers`](/api-reference/endpoint/amazon/bestsellers) | GET | Top-selling products by category | | [`/v1/amazon/new-releases`](/api-reference/endpoint/amazon/new-releases) | GET | Newly released products by category | | [`/v1/amazon/deals`](/api-reference/endpoint/amazon/deals) | GET | Current deals and lightning deals | | [`/v1/amazon/category`](/api-reference/endpoint/amazon/browse-category) | GET | List products within a browse-node category | | [`/v1/amazon/sellers/{seller_id}`](/api-reference/endpoint/amazon/get-seller) | GET | Seller profile and feedback summary | | [`/v1/amazon/sellers/{seller_id}/products`](/api-reference/endpoint/amazon/seller-products) | GET | Seller storefront listings | | [`/v1/amazon/sellers/{seller_id}/feedback`](/api-reference/endpoint/amazon/seller-feedback) | GET | Buyer feedback entries for a seller | | [`/v1/amazon/markets`](/api-reference/endpoint/amazon/list-markets) | GET | List all supported marketplaces | | [`/v1/amazon/categories`](/api-reference/endpoint/amazon/list-categories) | GET | List department/category aliases | ## Credit Costs | Endpoint | Cost | | - | - | | Search products | 5 credits | | Get product detail | 10 credits | | Get offers | 8 credits | | Get reviews | 10 credits | | Bestsellers | 5 credits | | New releases | 5 credits | | Deals | 5 credits | | Browse category | 5 credits | | Get seller | 3 credits | | Seller products | 5 credits | | Seller feedback | 3 credits | | Autocomplete | 1 credit | | List markets | 0 credits | | List categories | 0 credits | | Failed requests | 0 credits | ## Authentication All requests require your API key in the `X-API-Key` header: ```bash theme={null} curl "https://scrapebadger.com/v1/amazon/search?query=laptop" \ -H "X-API-Key: YOUR_API_KEY" ``` ## Anti-Bot Handling Amazon protects its catalog with AWS WAF, IP-reputation scoring, and TLS/HTTP-2 fingerprinting. ScrapeBadger clears these automatically using Chrome TLS impersonation on fresh **residential** sessions matched to the target marketplace, plus an origin-warmup step that seeds a clean WAF-passing session before guarded endpoints (offers, autocomplete) are fetched. You never need to manage proxies, sessions, or CAPTCHAs. For accurate pricing and availability, requests are routed through residential proxies in the marketplace's country. This is handled automatically based on the `domain` parameter. ## Next Steps Full API reference for searching the Amazon catalog Retrieve full product detail for a specific ASIN *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Amazon. "Amazon" is a trademark of Amazon.com, Inc., used here only to describe the platform this scraper is designed to work with.* # Apartments.com Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/apartments/overview Scrape apartments.com US rental listings as structured JSON — search by location with bed and price filters, plus unit-level pricing: every rentable unit's rent, beds, baths, square footage and availability date. ## Scraper API for Apartments.com Search **US rental listings** and pull **unit-level inventory** — not just a property's advertised range, but every individual rentable unit with its own rent, beds, baths, square footage and availability date. Authentication and anti-bot bypass are handled automatically. ## Key Features Every rentable unit with its **own rent**, beds, baths, sqft and availability date — not just the property's advertised range. Each floor-plan model with its price range, bed/bath count, square footage and the units belonging to it. 40 property cards a page, filterable by bedroom count and price. Pages `1`-`28`. Name, full address with city/state/ZIP, geo coordinates, phone, amenities, office hours and photo gallery. apartments.com is fully server-rendered, so responses come back in **\~2 seconds** with no browser in the path. GreatSchools ratings, grade ranges, enrollment and whether the property is in each school's **attendance zone**. apartments.com sits behind Akamai Bot Manager. ScrapeBadger clears it automatically — no proxies or CAPTCHAs to manage. **Use `rent`, not `max_term_rent`.** Each unit carries both. `rent` is the advertised price the site shows a renter. `max_term_rent` is apartments.com's raw `data-maxrent` attribute, which measures roughly **twice** the advertised rent and appears to be an upper bound across lease terms. It is exposed unparsed for completeness — do not treat it as the rent. ## Coverage Single market: **apartments.com** (US, USD, en-US). ## Endpoints | Endpoint | Description | Credits | | - | - | - | | [`GET /v1/apartments/search`](/api-reference/endpoint/apartments/search-listings) | Search rentals by location, 40 cards a page | 5 | | [`GET /v1/apartments/property`](/api-reference/endpoint/apartments/get-property) | One property with floor plans and per-unit inventory | 5 | | `GET /v1/apartments/properties/{slug}/{property_id}` | The same detail, addressed by parts | 5 | ## Search Filters Every filter below was verified against live result counts. Measured on `kansas-city-mo` (700 properties unfiltered): | Filter | Result count | | - | - | | *(none)* | 700 | | `beds=0` (studios) | 145 | | `beds=1` | 374 | | `beds=2` | 490 | | `max_price=1500` | 646 | | `min_price=1000&max_price=1500` | 546 | | `beds=1&max_price=1500` | 320 | apartments.com also renders a pet filter, but it returns the **unfiltered** total, so it is deliberately not exposed — a filter that silently does nothing is worse than no filter. ## Quickstart ```bash cURL theme={null} # Search curl -H "X-API-Key: YOUR_KEY" \ "https://scrapebadger.com/v1/apartments/search?location=kansas-city-mo&beds=1" # Property detail with per-unit pricing curl -H "X-API-Key: YOUR_KEY" \ "https://scrapebadger.com/v1/apartments/property?url=https%3A%2F%2Fwww.apartments.com%2Furbane-kansas-city-mo%2Fwcd6e5k%2F" ``` ```python Python theme={null} from scrapebadger import ScrapeBadger async with ScrapeBadger(api_key="YOUR_KEY") as client: page = await client.apartments.search("kansas-city-mo", beds=1, max_price=1500) print(f"{page.total_results} rentals") prop = await client.apartments.get_property(page.results[0].url) for unit in prop.units: print(unit.unit_number, unit.rent, unit.beds, unit.sqft, unit.available_text) ``` ```typescript Node.js theme={null} import { ScrapeBadger } from "@scrapebadger/sdk"; const client = new ScrapeBadger({ apiKey: "YOUR_KEY" }); const page = await client.apartments.search("kansas-city-mo", { beds: 1, maxPrice: 1500 }); const prop = await client.apartments.getProperty(page.results[0].url!); for (const unit of prop.units) { console.log(unit.unit_number, unit.rent, unit.available_text); } ``` ```bash CLI theme={null} scrapebadger apartments search kansas-city-mo --beds 1 --max-price 1500 -o table scrapebadger apartments units "https://www.apartments.com/urbane-kansas-city-mo/wcd6e5k/" -o table ``` ## Finding a location slug `location` is the slug apartments.com uses in its own URLs — the segment right after the domain. | Place | Slug | | - | - | | Kansas City, MO | `kansas-city-mo` | | New York, NY | `new-york-ny` | | Austin, TX | `austin-tx` | | A ZIP code | `64108` | ## Notes on the data `available_text` is verbatim as rendered — `"Now"`, `"Sep 3"`. The site prints no year, so converting it to a timestamp would mean guessing the rollover. It is left as text deliberately. A floor plan with `units_available: 0` and valid beds/baths/rent/sqft is the site's own layout for that property, not missing data. Those properties advertise plans rather than individual units. `rating` is the GreatSchools score out of 10. apartments.com renders **no badge** for schools it has no rating for, so those come back as `null`. They are never `0` — a 0 would mean "rated zero", which is a different and much worse claim about a school. A search card carries a rent/bed **rollup** (`"1 Bed"`, `"$1,559+"`), not per-unit inventory. Pass the card's `url` to the property endpoint for units. If you scrape apartments.com through the general [Web Scraping API](/web-scraping/overview) instead of this one, do **not** pass `render_js: true`. The whole page is server-rendered, so JS rendering only forces the slow browser path — 100+ seconds per page, which can exceed the CDN timeout and return a `524`. *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Apartments.com or CoStar Group, Inc. "Apartments.com" is a trademark of CoStar Group, Inc., used here only to describe the platform this scraper is designed to work with.* # Get Account Info Source: https://docs.scrapebadger.com/api-reference/endpoint/account/get-account-info get /v1/account/me Check your credit balances, subscription details, plan tier, and rate limits. No credits are deducted for this call. This endpoint is useful for monitoring your credit balance programmatically — e.g., before running a batch job or in a CI pipeline. It returns both PAYG and subscription credit balances, plus full subscription details if you're on a plan. **No credits are deducted.** # Get Availability Calendar Source: https://docs.scrapebadger.com/api-reference/endpoint/airbnb/get-calendar GET https://scrapebadger.com/v1/airbnb/listings/{room_id}/calendar Day-by-day Airbnb availability and pricing — up to 12 months of check-in / check-out eligibility, min and max nights, and nightly price. Fetch a listing's availability calendar by `room_id`. Each day carries whether it is available, whether it is bookable, whether it can be used as a check-in or check-out date, the minimum and maximum stay length, and the nightly price. Request up to twelve months from a starting `month` / `year`. ## Path Parameters Airbnb room id, e.g. `48291736`. ## Query Parameters Starting month, `1`–`12`. Starting year. Number of months to return, `1`–`12`. Currency for prices, e.g. `EUR`, `GBP`. Locale for text, e.g. `fr`, `es`. ## Response Airbnb room id. One entry per requested month, in order. Month number, `1`–`12`. Every day in that month. `YYYY-MM-DD`. Not blocked or already booked. Can actually be booked, respecting stay rules. Usable as a check-in date. Usable as a check-out date. Minimum stay length starting on this date. Maximum stay length starting on this date. Formatted nightly price, e.g. `€172` — `null` when Airbnb hides it. ## Example ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/airbnb/listings/48291736/calendar?" + new URLSearchParams({ month: "9", year: "2026", months: "3", currency: "EUR", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const calendar = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/airbnb/listings/48291736/calendar", headers={"X-API-Key": "YOUR_API_KEY"}, params={"month": 9, "year": 2026, "months": 3, "currency": "EUR"}, ) calendar = res.json() ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/airbnb/listings/48291736/calendar?month=9&year=2026&months=3¤cy=EUR" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} { "room_id": "48291736", "months": [ { "month": 9, "year": 2026, "days": [ { "date": "2026-09-01", "available": false, "bookable": false, "available_for_checkin": false, "available_for_checkout": false, "min_nights": 2, "max_nights": 28, "price": null }, { "date": "2026-09-12", "available": true, "bookable": true, "available_for_checkin": true, "available_for_checkout": false, "min_nights": 3, "max_nights": 28, "price": "€172" }, { "date": "2026-09-13", "available": true, "bookable": true, "available_for_checkin": true, "available_for_checkout": true, "min_nights": 2, "max_nights": 28, "price": "€168" } ] }, { "month": 10, "year": 2026, "days": [ { "date": "2026-10-01", "available": true, "bookable": true, "available_for_checkin": true, "available_for_checkout": true, "min_nights": 2, "max_nights": 28, "price": "€145" } ] } ] } ``` Each calendar request costs **5 credits**. Failed requests are not charged. # Get Experience Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/airbnb/get-experience GET https://scrapebadger.com/v1/airbnb/experiences/{experience_id} Full Airbnb Experience detail — description, rating, highlights, host, price, address, GPS and all photos. Fetch a single experience's complete detail by its `experience_id` (from [`/experiences`](/api-reference/endpoint/airbnb/search-experiences) or an Airbnb URL such as `airbnb.com/experiences/1847362`). Guest counts shape the price context Airbnb returns. ## Path Parameters Airbnb experience id, e.g. `1847362`. ## Query Parameters Number of adults. Number of children. Number of infants. Currency for prices, e.g. `EUR`, `GBP`. Locale for text, e.g. `fr`, `es`. ## Response Airbnb experience id. Full experience description. Average rating. Number of reviews. Ticketed (Airbnb Original) experience. Meeting point as shown by Airbnb. Experience host. What the experience includes, e.g. `Food and drinks`. All experience photo URLs. Formatted price, e.g. `€45 / person`. Canonical experience URL on airbnb.com. ## Example ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/airbnb/experiences/1847362?adults=2¤cy=EUR", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const experience = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/airbnb/experiences/1847362", headers={"X-API-Key": "YOUR_API_KEY"}, params={"adults": 2, "currency": "EUR"}, ) experience = res.json() ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/airbnb/experiences/1847362?adults=2¤cy=EUR" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} { "experience_id": "1847362", "title": "Trastevere street food walk with a Roman chef", "description": "We start at the Piazza San Cosimato market, taste supplì at a family fry shop that has been open since 1954, cut through the back lanes for porchetta and pecorino, and finish with a proper maritozzo. I cook in Rome for a living, so expect opinions about carbonara. Vegetarian route available on request.", "rating": 4.96, "review_count": 1204, "is_ticketed": false, "latitude": 41.8894, "longitude": 12.4692, "address": "Piazza San Cosimato, Trastevere, Rome, Italy", "host_name": "Giulia", "highlights": [ "Food and drinks included", "Small group — 8 guests maximum", "Hosted in Italian and English" ], "images": [ "https://a0.muscache.com/im/pictures/experience/1847362-supplice.jpeg", "https://a0.muscache.com/im/pictures/experience/1847362-market.jpeg", "https://a0.muscache.com/im/pictures/experience/1847362-maritozzo.jpeg" ], "price": "€45 / person", "experience_url": "https://www.airbnb.com/experiences/1847362" } ``` Each experience-detail request costs **5 credits**. Failed requests are not charged. # Get Listing Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/airbnb/get-listing GET https://scrapebadger.com/v1/airbnb/listings/{room_id} Full Airbnb listing detail — description, capacity, GPS, rating breakdown, amenities, house rules, cancellation policy, host profile and all photos. Fetch a single listing's complete detail by its `room_id` (from [`/search`](/api-reference/endpoint/airbnb/search) or an Airbnb URL such as `airbnb.com/rooms/48291736`). The response carries everything the search card has, plus the full description, the six-category rating breakdown, every amenity, the house rules, and the host profile. ## Path Parameters Airbnb room id, e.g. `48291736`. ## Query Parameters Number of adults — affects the price context returned by Airbnb. Currency for prices, e.g. `EUR`, `GBP`. Locale for text, e.g. `fr`, `es`. ## Response Airbnb room id. Listing headline. One-line summary, e.g. `Rental unit in Lisbon · ★4.8 · 1 bedroom · 1 bed · 1 bath`. Full listing description. e.g. `Entire home/apt`. Maximum number of guests. Approximate address as shown by Airbnb. Average rating. Number of reviews. Host holds Superhost status. Listing highlights, e.g. `Self check-in`. Every amenity Airbnb lists, including unavailable ones. Amenity id. e.g. `Wifi`. Extra detail, e.g. `Fast · 220 Mbps`. `false` = listed as not offered. Amenity group, e.g. `Bathroom`, `Kitchen and dining`. House rules as displayed. Cancellation policy summary. Host bio. e.g. `Lives in Lisbon, Portugal`. e.g. `within an hour`. Host avatar URL. All listing photo URLs. Canonical listing URL on airbnb.com. ## Example ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/airbnb/listings/48291736?adults=2¤cy=EUR", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const listing = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/airbnb/listings/48291736", headers={"X-API-Key": "YOUR_API_KEY"}, params={"adults": 2, "currency": "EUR"}, ) listing = res.json() ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/airbnb/listings/48291736?adults=2¤cy=EUR" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} { "room_id": "48291736", "title": "Sunlit apartment in Alfama with river view", "summary": "Rental unit in Lisbon · ★4.8 · 1 bedroom · 1 bed · 1 bath", "description": "A bright top-floor apartment in the heart of Alfama, two minutes from the Miradouro de Santa Luzia. Original azulejos, a compact but fully equipped kitchen, and a small balcony looking over the Tagus. Trams 12 and 28 stop at the corner.", "room_type": "Entire home/apt", "person_capacity": 3, "latitude": 38.7118, "longitude": -9.1294, "address": "Alfama, Lisbon, Portugal", "rating": 4.83, "review_count": 214, "rating_breakdown": { "accuracy": 4.9, "checkin": 4.95, "cleanliness": 4.78, "communication": 4.97, "location": 4.88, "value": 4.62 }, "is_superhost": true, "highlights": [ "Self check-in", "Great location", "Free cancellation for 48 hours" ], "amenities": [ { "id": "4", "title": "Wifi", "subtitle": "Fast · 220 Mbps", "available": true, "group": "Internet and office" }, { "id": "8", "title": "Kitchen", "subtitle": "Space where guests can cook their own meals", "available": true, "group": "Kitchen and dining" }, { "id": "41", "title": "Elevator", "subtitle": null, "available": false, "group": "Accessibility" } ], "house_rules": [ "Check-in after 3:00 PM", "Checkout before 11:00 AM", "3 guests maximum", "No smoking", "No parties or events" ], "cancellation_policy": "Free cancellation before Sep 7. Cancel before check-in on Sep 12 for a partial refund.", "host": { "name": "Inês", "is_superhost": true, "about": "Born and raised in Lisbon. I restore old apartments and love pointing guests to the places tourists miss.", "highlights": [ "Lives in Lisbon, Portugal", "Speaks Portuguese, English, Spanish" ], "response_time": "within an hour", "profile_image": "https://a0.muscache.com/im/pictures/user/9f2a1c-profile.jpg" }, "images": [ "https://a0.muscache.com/im/pictures/miso/Hosting-48291736/original/2c8f1a44-living.jpeg", "https://a0.muscache.com/im/pictures/miso/Hosting-48291736/original/8e3b7d19-bedroom.jpeg", "https://a0.muscache.com/im/pictures/miso/Hosting-48291736/original/b71e0c25-balcony.jpeg" ], "listing_url": "https://www.airbnb.com/rooms/48291736" } ``` Each listing-detail request costs **5 credits**. Failed requests are not charged. # Get Reviews Source: https://docs.scrapebadger.com/api-reference/endpoint/airbnb/get-reviews GET https://scrapebadger.com/v1/airbnb/listings/{room_id}/reviews Paginated Airbnb guest reviews — full text, per-review rating, language, reviewer profile, host response and photos. Page through a listing's guest reviews by `room_id`. Each review carries the full comment text, the guest's rating, the review language, the reviewer's profile, the host's response when there is one, and any photos the guest attached. Paginate with `limit` and `offset` against `total_count`. ## Path Parameters Airbnb room id, e.g. `48291736`. ## Query Parameters Reviews per page. Maximum `50`. Number of reviews to skip. Sort order. One of `MOST_RECENT`, `RATING_DESC`, `RATING_ASC`. Currency for prices, e.g. `EUR`, `GBP`. Locale for text, e.g. `fr`, `es`. ## Response Airbnb room id. Total reviews on the listing. Echo of the requested page size. Echo of the requested offset. Reviews for this page. Airbnb review id. Full review text. Guest rating, `1`–`5`. Language code the review was written in, e.g. `en`. Publication timestamp (ISO 8601). Airbnb's relative date, e.g. `2 days ago`. Guest's stated location. Guest avatar URL. Host's public reply, or `null`. Photo URLs attached to the review. ## Example ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/airbnb/listings/48291736/reviews?" + new URLSearchParams({ limit: "50", offset: "0", sort: "MOST_RECENT" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/airbnb/listings/48291736/reviews", headers={"X-API-Key": "YOUR_API_KEY"}, params={"limit": 50, "offset": 0, "sort": "MOST_RECENT"}, ) data = res.json() ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/airbnb/listings/48291736/reviews?limit=50&offset=0&sort=MOST_RECENT" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} { "room_id": "48291736", "total_count": 214, "limit": 50, "offset": 0, "reviews": [ { "id": "1284739201", "comments": "Inês's place is exactly as pictured — the balcony view over the Tagus is worth the four flights of stairs. Spotless, quiet at night despite being right by tram 28, and she left us a map of her favourite tascas. Would stay again.", "rating": 5, "language": "en", "created_at": "2026-08-12T09:41:22Z", "localized_date": "2 days ago", "reviewer_name": "Daniel", "reviewer_id": "38472910", "reviewer_location": "Dublin, Ireland", "reviewer_image": "https://a0.muscache.com/im/pictures/user/38472910-profile.jpg", "response": "Thank you Daniel! You were wonderful guests — come back any time.", "photos": [ "https://a0.muscache.com/im/pictures/review/1284739201-balcony.jpeg" ] }, { "id": "1281002934", "comments": "Très bien situé, appartement propre et bien équipé. Un peu bruyant le matin à cause du tram, mais rien de grave.", "rating": 4, "language": "fr", "created_at": "2026-07-30T18:02:10Z", "localized_date": "2 weeks ago", "reviewer_name": "Camille", "reviewer_id": "19283746", "reviewer_location": "Lyon, France", "reviewer_image": "https://a0.muscache.com/im/pictures/user/19283746-profile.jpg", "response": null, "photos": [] } ] } ``` Each reviews request costs **5 credits**. Failed requests are not charged. # Search Stays Source: https://docs.scrapebadger.com/api-reference/endpoint/airbnb/search GET https://scrapebadger.com/v1/airbnb/search Search Airbnb stays by place name or map bounding box — with dates, guest counts, price, bedrooms, beds, bathrooms and room-type filters. Search Airbnb for stays. Target an area either with free-text `location` (geocoded server-side) **or** with a precise map bounding box (`ne_lat` / `ne_lng` / `sw_lat` / `sw_lng`, all four together). Page through results by feeding `next_page_cursor` back as `cursor`. ## Query Parameters Free-text place, geocoded server-side — e.g. `Paris, France`, `Lisbon`, `Trastevere, Rome`. Provide either `location` **or** the bounding-box parameters below. North-east corner latitude of the map bounding box. Requires `ne_lng`, `sw_lat` and `sw_lng`. North-east corner longitude of the map bounding box. South-west corner latitude of the map bounding box. South-west corner longitude of the map bounding box. Check-in date, `YYYY-MM-DD`. Check-out date, `YYYY-MM-DD`. Number of adults. Number of children. Number of infants. Number of pets. Minimum nightly price, in `currency`. Maximum nightly price, in `currency`. Minimum number of bedrooms. Minimum number of beds. Minimum number of bathrooms. Room type. One of `Entire home/apt`, `Private room`, `Shared room`, `Hotel room`. Pagination cursor — pass the `next_page_cursor` from the previous response. Listings per page. Maximum `50`. Currency for prices, e.g. `EUR`, `GBP`. Locale for text, e.g. `fr`, `es`. ## Response Echo of the resolved search area. Listings returned on this page. Cursor for the next page — pass it back as `cursor`. `null` on the last page. Listing cards for this page. Airbnb room id — feed to [`/listings/{room_id}`](/api-reference/endpoint/airbnb/get-listing), [`/calendar`](/api-reference/endpoint/airbnb/get-calendar) and [`/reviews`](/api-reference/endpoint/airbnb/get-reviews). Short listing name, e.g. `Rental unit in Paris`. Listing headline. Average rating, e.g. `4.87`. Number of reviews. Formatted rating, e.g. `4.8 (214)`. Full price line, e.g. `$182 per night`. Formatted price, e.g. `$182`. e.g. `per night`, `total`. Numeric price. e.g. `USD`. Struck-through price when discounted, else `null`. Airbnb badges, e.g. `["Guest favorite"]`. Photo URLs. Canonical listing URL on airbnb.com. ## Example ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/airbnb/search?" + new URLSearchParams({ location: "Paris, France", check_in: "2026-09-12", check_out: "2026-09-15", adults: "2", price_max: "250", room_type: "Entire home/apt", currency: "EUR", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/airbnb/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "location": "Paris, France", "check_in": "2026-09-12", "check_out": "2026-09-15", "adults": 2, "price_max": 250, "room_type": "Entire home/apt", "currency": "EUR", }, ) data = res.json() ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/airbnb/search?location=Paris%2C%20France&check_in=2026-09-12&check_out=2026-09-15&adults=2&price_max=250¤cy=EUR" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} { "query": "Paris, France", "count": 18, "next_page_cursor": "eyJzZWN0aW9uX29mZnNldCI6MCwiaXRlbXNfb2Zmc2V0IjoxOCwidmVyc2lvbiI6MX0=", "listings": [ { "room_id": "48291736", "name": "Rental unit in Paris", "title": "Sunlit Haussmannian flat near Canal Saint-Martin", "rating": 4.87, "review_count": 214, "rating_label": "4.8 (214)", "price": { "label": "€172 per night", "price": "€172", "qualifier": "per night", "amount": 172, "currency": "EUR", "original_price": "€215" }, "badges": ["Guest favorite"], "latitude": 48.8721, "longitude": 2.3648, "images": [ "https://a0.muscache.com/im/pictures/miso/Hosting-48291736/original/2c8f1a44-living.jpeg", "https://a0.muscache.com/im/pictures/miso/Hosting-48291736/original/8e3b7d19-bedroom.jpeg" ], "listing_url": "https://www.airbnb.com/rooms/48291736" }, { "room_id": "1029384756", "name": "Condo in Paris", "title": "Quiet studio in Le Marais with balcony", "rating": 4.92, "review_count": 88, "rating_label": "4.9 (88)", "price": { "label": "€139 per night", "price": "€139", "qualifier": "per night", "amount": 139, "currency": "EUR", "original_price": null }, "badges": [], "latitude": 48.8566, "longitude": 2.3622, "images": [ "https://a0.muscache.com/im/pictures/miso/Hosting-1029384756/original/44a1c9f0-studio.jpeg" ], "listing_url": "https://www.airbnb.com/rooms/1029384756" } ] } ``` Each search request costs **5 credits**. Failed requests are not charged. # Search Experiences Source: https://docs.scrapebadger.com/api-reference/endpoint/airbnb/search-experiences GET https://scrapebadger.com/v1/airbnb/experiences Search Airbnb Experiences by location — title, duration, rating, price, GPS and photos, with cursor pagination. Search Airbnb **Experiences** in a place. `location` is required and geocoded server-side. Page through results by feeding `next_page_cursor` back as `cursor`, then fetch full detail with [`/experiences/{experience_id}`](/api-reference/endpoint/airbnb/get-experience). ## Query Parameters Free-text place, geocoded server-side — e.g. `Rome, Italy`, `Lisbon`. Pagination cursor — pass the `next_page_cursor` from the previous response. Currency for prices, e.g. `EUR`, `GBP`. Locale for text, e.g. `fr`, `es`. ## Response Echo of the resolved location. Experiences returned on this page. Cursor for the next page — pass it back as `cursor`. `null` on the last page. Experience cards for this page. Airbnb experience id — feed to [`/experiences/{experience_id}`](/api-reference/endpoint/airbnb/get-experience). e.g. `2.5 hours`. Average rating, e.g. `4.96`. Number of reviews. Formatted rating, e.g. `4.96 (1,204)`. Formatted price, e.g. `€45 / person`. Photo URLs. Canonical experience URL on airbnb.com. ## Example ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/airbnb/experiences?" + new URLSearchParams({ location: "Rome, Italy", currency: "EUR" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/airbnb/experiences", headers={"X-API-Key": "YOUR_API_KEY"}, params={"location": "Rome, Italy", "currency": "EUR"}, ) data = res.json() ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/airbnb/experiences?location=Rome%2C%20Italy¤cy=EUR" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} { "location": "Rome, Italy", "count": 20, "next_page_cursor": "eyJpdGVtc19vZmZzZXQiOjIwLCJ2ZXJzaW9uIjoxfQ==", "experiences": [ { "experience_id": "1847362", "title": "Trastevere street food walk with a Roman chef", "duration": "2.5 hours", "rating": 4.96, "review_count": 1204, "rating_label": "4.96 (1,204)", "price": "€45 / person", "latitude": 41.8894, "longitude": 12.4692, "images": [ "https://a0.muscache.com/im/pictures/experience/1847362-supplice.jpeg", "https://a0.muscache.com/im/pictures/experience/1847362-market.jpeg" ], "experience_url": "https://www.airbnb.com/experiences/1847362" }, { "experience_id": "2938471", "title": "Sunrise photography tour of the Roman Forum", "duration": "3 hours", "rating": 4.89, "review_count": 372, "rating_label": "4.89 (372)", "price": "€68 / person", "latitude": 41.8925, "longitude": 12.4853, "images": [ "https://a0.muscache.com/im/pictures/experience/2938471-forum.jpeg" ], "experience_url": "https://www.airbnb.com/experiences/2938471" } ] } ``` Each experiences-search request costs **5 credits**. Failed requests are not charged. # Keyword Suggestions Source: https://docs.scrapebadger.com/api-reference/endpoint/amazon/autocomplete GET /v1/amazon/autocomplete Get Amazon search autocomplete suggestions for keyword research. ## Query Parameters Partial search term to expand into suggestions. Example: `wireless ear` Amazon marketplace TLD or code. Suggestions are localized per marketplace. Examples: `com`, `co.uk`, `de` ## Response The partial term that was expanded. Marketplace the suggestions came from. Array of suggested search phrases. Suggested search phrase. Department alias the suggestion is scoped to, if any (nullable). ### Example Response ```json theme={null} { "query": "wireless ear", "domain": "com", "suggestions": [ { "value": "wireless earbuds", "alias": "aps" }, { "value": "wireless earbuds bluetooth", "alias": "aps" }, { "value": "wireless earphones", "alias": "electronics" } ] } ``` Each autocomplete request costs **1 credit**. Failed requests are not charged. # Bestsellers Source: https://docs.scrapebadger.com/api-reference/endpoint/amazon/bestsellers GET /v1/amazon/bestsellers Top-selling products for a category (browse node). ## Query Parameters Amazon marketplace TLD or code. Examples: `com`, `co.uk`, `de` Bestsellers node id or category slug. Use [`/v1/amazon/categories`](/api-reference/endpoint/amazon/list-categories) to look up nodes. Defaults to the marketplace's electronics grid on `.com`. Example: `electronics`, `books` Page number. Each page covers 50 ranks. Range: `1` - `2`. ## Response Marketplace domain. Category/node the list was pulled from (nullable). Array of ranked bestseller products. Best-seller rank. Position on the page. Product ASIN. Product title. Full URL to the product page. Primary product image URL. Average star rating (nullable). Total number of ratings (nullable). Price object with `value`, `currency`, `symbol`, `raw`. ### Example Response ```json theme={null} { "domain": "com", "category": "electronics", "results": [ { "rank": 1, "position": 1, "asin": "B09B8V1LZ3", "title": "Apple AirTag", "link": "https://www.amazon.com/dp/B09B8V1LZ3", "image": "https://m.media-amazon.com/images/I/71abc.jpg", "rating": 4.7, "ratings_total": 412300, "price": { "value": 24.0, "currency": "USD", "symbol": "$", "raw": "$24.00" } } ] } ``` Each bestsellers request costs **5 credits**. Failed requests are not charged. # Browse Category Source: https://docs.scrapebadger.com/api-reference/endpoint/amazon/browse-category GET /v1/amazon/category List products within an Amazon browse-node category. ## Query Parameters Amazon browse-node id to list products from. You can find browse-node ids in product `bestsellers_rank` links or category URLs (`node=...`). Amazon marketplace TLD or code. Examples: `com`, `co.uk`, `de` Page number for paginated results. Range: `1` - `20`. Sort order for results. | Value | Description | | - | - | | `relevance` | Best match (default) | | `price_low_to_high` | Cheapest first | | `price_high_to_low` | Most expensive first | | `avg_review` | Highest customer rating first | | `newest` | Most recently added | ## Response The browse-node id that was listed. Marketplace domain. Array of products in the category. Position on the page (1-based). Product ASIN. Product title. Full URL to the product page. Primary product image URL. Price object with `value`, `currency`, `symbol`, `raw`. Average star rating (nullable). Total number of ratings (nullable). Whether the item is Prime-eligible. Best Seller badge present. Availability/stock message. Pagination metadata with `current_page`, `total_pages`, `total_results`. ### Example Response ```json theme={null} { "node": "172282", "domain": "com", "results": [ { "position": 1, "asin": "B0CHWRXH8B", "title": "Bose QuietComfort Ultra Wireless Earbuds", "link": "https://www.amazon.com/dp/B0CHWRXH8B", "image": "https://m.media-amazon.com/images/I/61abc123.jpg", "price": { "value": 249.0, "currency": "USD", "symbol": "$", "raw": "$249.00" }, "rating": 4.4, "ratings_total": 12480, "is_prime": true, "is_best_seller": true, "availability": "In Stock" } ], "pagination": { "current_page": 1, "total_pages": 20, "total_results": 660 } } ``` Each category request costs **5 credits**. Failed requests are not charged. # Today's Deals Source: https://docs.scrapebadger.com/api-reference/endpoint/amazon/deals GET /v1/amazon/deals Current Amazon deals (lightning deals, best deals). ## Query Parameters Amazon marketplace TLD or code. Examples: `com`, `co.uk`, `de` Category alias to scope the deals feed. Use [`/v1/amazon/categories`](/api-reference/endpoint/amazon/list-categories) to look up aliases. Page number for paginated deals. Starts at `1`. ## Response Marketplace domain. Category the deals were scoped to (nullable). Array of current deals. Position in the deals feed. Product ASIN. Product title. Full URL to the product page. Primary product image URL. Discounted deal price with `value`, `currency`, `symbol`, `raw`. Original list price. Discount percentage (nullable). Deal type label (e.g. `Best Deal`, `Lightning Deal`). Whether this is a time-limited lightning deal. Promotional badge text (nullable). ISO 8601 timestamp when the deal ends, if available (nullable). ### Example Response ```json theme={null} { "domain": "com", "category": null, "results": [ { "position": 1, "asin": "B0C7KMR3T5", "title": "Sony WH-1000XM5 Wireless Headphones", "link": "https://www.amazon.com/dp/B0C7KMR3T5", "image": "https://m.media-amazon.com/images/I/61deal.jpg", "deal_price": { "value": 298.0, "currency": "USD", "symbol": "$", "raw": "$298.00" }, "list_price": { "value": 399.99, "currency": "USD", "symbol": "$", "raw": "$399.99" }, "discount_percent": 25, "deal_type": "Best Deal", "is_lightning_deal": false, "badge": "Limited time deal", "ends_at": null } ] } ``` Each deals request costs **5 credits**. Failed requests are not charged. # Get Offers Source: https://docs.scrapebadger.com/api-reference/endpoint/amazon/get-offers GET /v1/amazon/products/{asin}/offers All third-party offers for an ASIN, including the Buy Box winner. ## Path Parameters The ASIN of the product to list offers for. ## Query Parameters Amazon marketplace TLD or code where the product is listed. Examples: `com`, `co.uk`, `de` Delivery postal/zip code for localized offers and delivery estimates. Offer page. Amazon lists 10 seller offers per page; page 1 also carries the Buy Box offer. Compare `total_offers` with the number of offers returned to know whether more pages exist. ## Response The ASIN the offers belong to. Marketplace domain. The Buy Box offer (page 1 only). Same shape as an offer; also the first entry of `offers`. Amazon's total offer count across all pages, including the Buy Box offer. Larger than the number of offers returned when more pages exist; `null` on pages after the first. Array of seller offers, ordered with the Buy Box winner first. Position in the offer list. Seller summary: `name`, `id`, `link`, `rating`, `ratings_total`, `ratings_percentage_positive`. Offer price with `value`, `currency`, `symbol`, `raw`. Condition with `is_new`, `title`, `comments`. Delivery info: `is_free`, `fulfilled_by_amazon`, `date`, `price`. Whether this offer currently wins the Buy Box. Whether the offer is Prime-eligible. Minimum order quantity (nullable). Maximum order quantity (nullable). ### Example Response ```json theme={null} { "asin": "B08N5WRWNW", "domain": "com", "total_offers": 2, "offers": [ { "position": 1, "seller": { "name": "Amazon.com", "id": "ATVPDKIKX0DER", "rating": 4.7, "ratings_total": 1284000, "ratings_percentage_positive": 96 }, "price": { "value": 49.99, "currency": "USD", "symbol": "$", "raw": "$49.99" }, "condition": { "is_new": true, "title": "New", "comments": null }, "delivery": { "is_free": true, "fulfilled_by_amazon": true, "date": "2026-06-04", "price": null }, "buybox_winner": true, "is_prime": true, "minimum_order_quantity": 1, "maximum_order_quantity": 30 }, { "position": 2, "seller": { "name": "TechDeals Store", "id": "A1B2C3D4E5F6G7", "rating": 4.6, "ratings_total": 8421, "ratings_percentage_positive": 94 }, "price": { "value": 47.5, "currency": "USD", "symbol": "$", "raw": "$47.50" }, "condition": { "is_new": true, "title": "New", "comments": null }, "delivery": { "is_free": false, "fulfilled_by_amazon": false, "date": "2026-06-08", "price": { "value": 4.99, "currency": "USD", "symbol": "$", "raw": "$4.99" } }, "buybox_winner": false, "is_prime": false, "minimum_order_quantity": 1, "maximum_order_quantity": 10 } ] } ``` Each offers request costs **8 credits**. Single-seller products return an empty `offers` array. Failed requests are not charged. # Get Product Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/amazon/get-product GET /v1/amazon/products/{asin} Full product detail by ASIN (price, variants, badges, buybox, ranks, ...). ## Path Parameters The Amazon Standard Identification Number (ASIN) of the product. You can find this in search results or extract it from a product URL (`/dp/{ASIN}`). ## Query Parameters Amazon marketplace TLD or code where the product is listed. Examples: `com`, `co.uk`, `de`, `fr` Delivery postal/zip code for a localized buybox and delivery estimate. Locale for the product page, e.g. `en_US`, `de_DE`. ## Response Marketplace domain the product was fetched from. Full product object. Product ASIN. Parent ASIN if the product is a variation child (nullable). Product title. Brand name. Current price with `value`, `currency`, `symbol`, `raw`. Strikethrough list price. Discount percentage off list price. Average star rating (0-5). Total number of ratings. Percentage of ratings per star bucket (`five_star` ... `one_star`). Bullet-point feature highlights. All product image URLs. Variation children with `asin`, `attributes`, `price`, `is_current`. Best-seller ranks with `rank`, `category`, `link`. Technical specifications map. Buy Box winner with `seller_name`, `seller_id`, `price`, `fulfillment`. Badge flags: `amazons_choice`, `best_seller`, `prime`, `climate_pledge_friendly`. ASINs frequently bought by the same customers. A handful of featured reviews. ISO 8601 timestamp when the product was scraped. ### Example Response ```json theme={null} { "domain": "com", "product": { "asin": "B08N5WRWNW", "title": "Echo Dot (4th Gen) Smart speaker with Alexa", "brand": "Amazon", "price": { "value": 49.99, "currency": "USD", "symbol": "$", "raw": "$49.99" }, "list_price": { "value": 59.99, "currency": "USD", "symbol": "$", "raw": "$59.99" }, "discount_percent": 17, "rating": 4.7, "ratings_total": 184231, "rating_breakdown": { "five_star": 78, "four_star": 13, "three_star": 4, "two_star": 2, "one_star": 3 }, "feature_bullets": ["Meet the Echo Dot - Our most popular smart speaker."], "images": ["https://m.media-amazon.com/images/I/714Rdc+abc.jpg"], "variants": [ { "asin": "B08N5WRWNW", "attributes": { "Color": "Charcoal" }, "is_current": true } ], "bestsellers_rank": [ { "rank": 334, "category": "Electronics", "link": "https://www.amazon.com/gp/bestsellers/electronics" }, { "rank": 1, "category": "Smart Speakers", "link": "https://www.amazon.com/gp/bestsellers/electronics/smart-speakers" } ], "specifications": { "Item Weight": "12 ounces" }, "buybox": { "seller_name": "Amazon.com", "seller_id": "ATVPDKIKX0DER", "fulfillment": "Amazon" }, "badges": { "amazons_choice": true, "best_seller": false, "prime": true, "climate_pledge_friendly": true }, "also_bought": ["B07FZ8S74R", "B08C1W5N87"], "top_reviews": [ { "id": "R1ABCDEF123456", "title": "Great little speaker", "rating": 5, "verified_purchase": true } ], "scraped_at": "2026-06-03T12:00:00Z" } } ``` Each product detail request costs **10 credits**. Failed requests are not charged. # Get Reviews Source: https://docs.scrapebadger.com/api-reference/endpoint/amazon/get-reviews GET /v1/amazon/products/{asin}/reviews Customer reviews for an ASIN (featured + paginated, with filters). ## Path Parameters The ASIN of the product to fetch reviews for. ## Query Parameters Amazon marketplace TLD or code where the product is listed. Examples: `com`, `co.uk`, `de` Page number for paginated reviews. Starts at `1` and is capped at `20`. Amazon exposes roughly 10 reviews per page, so this endpoint returns at most **\~200 reviews per product** (20 pages). Requesting a `page` beyond `20` returns no additional reviews. Sort order for reviews. | Value | Description | | - | - | | `helpful` | Most helpful first (default) | | `recent` | Most recent first | Filter reviews by star rating or sentiment. | Value | Description | | - | - | | `one_star` ... `five_star` | Reviews with that exact star rating | | `positive` | Positive reviews (4-5 stars) | | `critical` | Critical reviews (1-3 stars) | Only return reviews from verified purchases. Only return reviews that include images or video. ## Response The ASIN the reviews belong to. Marketplace domain. Overall average product rating. Total number of ratings for the product. Percentage of ratings per star bucket (`five_star` ... `one_star`). Array of reviews. Review ID. Review title. Full review text. Star rating left by the reviewer (1-5). Raw date string as shown on Amazon. ISO 8601 timestamp of the review. Country the review was written in. Reviewer profile: `name`, `link`, `id`, `image`. Whether the review is from a verified purchase. Whether the review is part of the Vine program. Number of helpful votes. Variant the review applies to (nullable). Review image URLs. Pagination metadata with `current_page`, `total_pages`, `total_results`. ### Example Response ```json theme={null} { "asin": "B08N5WRWNW", "domain": "com", "rating": 4.7, "ratings_total": 184231, "rating_breakdown": { "five_star": 78, "four_star": 13, "three_star": 4, "two_star": 2, "one_star": 3 }, "reviews": [ { "id": "R1ABCDEF123456", "title": "Great little speaker", "body": "Sound quality is excellent for the size. Setup was quick and Alexa is responsive.", "rating": 5, "date_raw": "Reviewed in the United States on May 28, 2026", "date_at": "2026-05-28T00:00:00Z", "review_country": "United States", "profile": { "name": "Jane D.", "link": "https://www.amazon.com/gp/profile/amzn1.account.ABC", "id": "amzn1.account.ABC", "image": "https://m.media-amazon.com/images/S/amazon-avatars/abc.png" }, "verified_purchase": true, "vine_program": false, "helpful_votes": 42, "variant": "Color: Charcoal", "images": ["https://m.media-amazon.com/images/I/71review1.jpg"] } ], "pagination": { "current_page": 1, "total_pages": 20, "total_results": 200 } } ``` Each reviews request costs **10 credits**. Amazon exposes a public *featured* subset of reviews; full review history is login-gated. The `page` parameter is capped at **20** (\~200 reviews per product) — there is no way to page deeper. Failed requests are not charged. # Get Seller Source: https://docs.scrapebadger.com/api-reference/endpoint/amazon/get-seller GET /v1/amazon/sellers/{seller_id} Seller profile, ratings and feedback summary. ## Path Parameters The Amazon seller ID (the value of the `seller=` URL parameter, e.g. from a `/sp?seller=...` link). ## Query Parameters Amazon marketplace TLD or code where the seller operates. Examples: `com`, `co.uk`, `de` ## Response Marketplace domain. Seller profile object. Seller ID. Seller display name. Full URL to the seller storefront. Average seller rating (0-5, nullable). Total number of seller ratings (nullable). Percentage of positive ratings (nullable). Feedback windows (`lifetime`, `12mo`, `90d`, `30d`), each with `positive`, `neutral`, `negative`, `count`. Registered business name (nullable). Registered business address (nullable). Year the seller joined (nullable). ### Example Response ```json theme={null} { "domain": "com", "seller": { "seller_id": "A1B2C3D4E5F6G7", "name": "TechDeals Store", "link": "https://www.amazon.com/sp?seller=A1B2C3D4E5F6G7", "rating": 4.6, "ratings_total": 8421, "ratings_percentage_positive": 94, "feedback": { "lifetime": { "positive": 94, "neutral": 2, "negative": 4, "count": 8421 }, "12mo": { "positive": 95, "neutral": 2, "negative": 3, "count": 2103 }, "90d": { "positive": 96, "neutral": 1, "negative": 3, "count": 540 }, "30d": { "positive": 97, "neutral": 1, "negative": 2, "count": 182 } }, "business_name": "TechDeals LLC", "business_address": "123 Commerce St, Seattle, WA 98101, US", "member_since": "2017" } } ``` Each seller request costs **3 credits**. Failed requests are not charged. # List Categories Source: https://docs.scrapebadger.com/api-reference/endpoint/amazon/list-categories GET /v1/amazon/categories List common Amazon department/category aliases and bestseller nodes. ## Query Parameters Amazon marketplace TLD or code. Category aliases are scoped per marketplace. Examples: `com`, `co.uk`, `de` ## Response Marketplace the aliases apply to. Array of category aliases. Category alias usable in the [search](/api-reference/endpoint/amazon/search-products) `category` parameter (the `i=` value). Human-readable department name. Browse-node slug usable with [bestsellers](/api-reference/endpoint/amazon/bestsellers) and [new releases](/api-reference/endpoint/amazon/new-releases) (nullable). ### Example Response ```json theme={null} { "domain": "com", "categories": [ { "alias": "electronics", "name": "Electronics", "bestsellers_node": "electronics" }, { "alias": "stripbooks", "name": "Books", "bestsellers_node": "books" }, { "alias": "fashion", "name": "Clothing, Shoes & Jewelry", "bestsellers_node": "fashion" }, { "alias": "toys-and-games", "name": "Toys & Games", "bestsellers_node": "toys-and-games" } ] } ``` The categories list is **free** (0 credits). # List Markets Source: https://docs.scrapebadger.com/api-reference/endpoint/amazon/list-markets GET /v1/amazon/markets List all supported Amazon marketplaces. ## Response Array of supported Amazon marketplaces. Market code (e.g. `"US"`, `"UK"`, `"DE"`). Amazon domain TLD to use in the `domain` query parameter (e.g. `"com"`, `"co.uk"`). Marketplace country name. ISO 4217 currency code used in this market. Default locale for this market. ISO country code used for proxy geo-targeting. ### Example Response ```json theme={null} { "markets": [ { "code": "US", "domain": "com", "name": "United States", "currency": "USD", "language": "en-US", "country_code": "US" }, { "code": "UK", "domain": "co.uk", "name": "United Kingdom", "currency": "GBP", "language": "en-GB", "country_code": "GB" }, { "code": "DE", "domain": "de", "name": "Germany", "currency": "EUR", "language": "de-DE", "country_code": "DE" }, { "code": "JP", "domain": "co.jp", "name": "Japan", "currency": "JPY", "language": "ja-JP", "country_code": "JP" } ] } ``` The markets list is **free** (0 credits). # New Releases Source: https://docs.scrapebadger.com/api-reference/endpoint/amazon/new-releases GET /v1/amazon/new-releases Newly released products for a category (browse node). ## Query Parameters Amazon marketplace TLD or code. Examples: `com`, `co.uk`, `de` New-releases node id or category slug. Use [`/v1/amazon/categories`](/api-reference/endpoint/amazon/list-categories) to look up nodes. Example: `electronics`, `books` Page number. Each page covers 50 ranks. Range: `1` - `2`. ## Response Marketplace domain. Category/node the list was pulled from (nullable). Array of newly released products. New-release rank. Position on the page. Product ASIN. Product title. Full URL to the product page. Primary product image URL. Average star rating (nullable). Total number of ratings (nullable). Price object with `value`, `currency`, `symbol`, `raw`. ### Example Response ```json theme={null} { "domain": "com", "category": "electronics", "results": [ { "rank": 1, "position": 1, "asin": "B0CX23V2ZK", "title": "Anker Prime Power Bank (2026)", "link": "https://www.amazon.com/dp/B0CX23V2ZK", "image": "https://m.media-amazon.com/images/I/61new.jpg", "rating": 4.6, "ratings_total": 842, "price": { "value": 129.99, "currency": "USD", "symbol": "$", "raw": "$129.99" } } ] } ``` Each new-releases request costs **5 credits**. Failed requests are not charged. # Search Products Source: https://docs.scrapebadger.com/api-reference/endpoint/amazon/search-products GET /v1/amazon/search Search the Amazon catalog with filters and sorting. ## Query Parameters Search keywords. Matches against product titles, brands, and descriptions. Amazon marketplace TLD or code. See [`/v1/amazon/markets`](/api-reference/endpoint/amazon/list-markets) for all supported values. Examples: `com`, `co.uk`, `de`, `fr`, `co.jp` Page number for paginated results. Range: `1` - `20`. Sort order for results. | Value | Description | | - | - | | `relevance` | Best match (default) | | `price_low_to_high` | Cheapest first | | `price_high_to_low` | Most expensive first | | `avg_review` | Highest customer rating first | | `newest` | Most recently added | Department/category alias to scope the search (the `i=` parameter). Use [`/v1/amazon/categories`](/api-reference/endpoint/amazon/list-categories) to look up aliases. Example: `electronics`, `stripbooks` Minimum price filter in the marketplace's local currency. Maximum price filter in the marketplace's local currency. Delivery postal/zip code for localized pricing and availability. Locale for results, e.g. `en_US`, `fr_FR`. ## Response The search query that was executed. Marketplace domain that was searched. Array of matching products. Position on the page (1-based). Amazon Standard Identification Number. Product title. Full URL to the product page. Primary product image URL. Price object with `value`, `currency`, `symbol`, `raw`. Strikethrough list price (nullable). Average star rating (0-5). Total number of ratings. Whether the item is Prime-eligible. Whether the result is a sponsored placement. Amazon's Choice badge present. Best Seller badge present. Purchase-volume hint (nullable). Availability/stock message. Pagination metadata with `current_page`, `total_pages`, `total_results`. ### Example Response ```json theme={null} { "query": "wireless earbuds", "domain": "com", "results": [ { "position": 1, "asin": "B0CHWRXH8B", "title": "Bose QuietComfort Ultra Wireless Earbuds", "link": "https://www.amazon.com/dp/B0CHWRXH8B", "image": "https://m.media-amazon.com/images/I/61abc123.jpg", "price": { "value": 249.0, "currency": "USD", "symbol": "$", "raw": "$249.00" }, "list_price": { "value": 299.0, "currency": "USD", "symbol": "$", "raw": "$299.00" }, "rating": 4.4, "ratings_total": 12480, "is_prime": true, "is_sponsored": false, "is_amazons_choice": true, "is_best_seller": false, "bought_past_month": "5K+ bought in past month", "availability": "In Stock" } ], "pagination": { "current_page": 1, "total_pages": 20, "total_results": 480 } } ``` Each search request costs **5 credits**. Failed requests are not charged. # Seller Feedback Source: https://docs.scrapebadger.com/api-reference/endpoint/amazon/seller-feedback GET /v1/amazon/sellers/{seller_id}/feedback Buyer feedback entries for a seller. ## Path Parameters The Amazon seller ID whose feedback to list. ## Query Parameters Amazon marketplace TLD or code where the seller operates. Examples: `com`, `co.uk`, `de` Page number for paginated feedback entries. Starts at `1`. ## Response The seller ID whose feedback was listed. Marketplace domain. Array of buyer feedback entries. Star rating left by the buyer (1-5). Feedback comment text. Raw date string as shown on Amazon. ISO 8601 timestamp of the feedback (nullable). Buyer display name, if shown (nullable). Pagination metadata with `current_page`, `total_pages`, `total_results`. ### Example Response ```json theme={null} { "seller_id": "A1B2C3D4E5F6G7", "domain": "com", "feedback": [ { "rating": 5, "body": "Fast shipping and item exactly as described. Would buy again.", "date_raw": "Reviewed on May 30, 2026", "date_at": "2026-05-30T00:00:00Z", "rater": "M. K." } ], "pagination": { "current_page": 1, "total_pages": 50, "total_results": 500 } } ``` Each seller feedback request costs **3 credits**. Failed requests are not charged. # Seller Products Source: https://docs.scrapebadger.com/api-reference/endpoint/amazon/seller-products GET /v1/amazon/sellers/{seller_id}/products Products listed in a seller's storefront. ## Path Parameters The Amazon seller ID whose storefront to list. ## Query Parameters Amazon marketplace TLD or code where the seller operates. Examples: `com`, `co.uk`, `de` Page number for paginated storefront results. Starts at `1`. ## Response The seller ID whose storefront was listed. Marketplace domain. Array of products in the seller storefront. Position on the page (1-based). Product ASIN. Product title. Full URL to the product page. Primary product image URL. Price object with `value`, `currency`, `symbol`, `raw`. Average star rating (nullable). Total number of ratings (nullable). Whether the item is Prime-eligible. Availability/stock message. Pagination metadata with `current_page`, `total_pages`, `total_results`. ### Example Response ```json theme={null} { "seller_id": "A1B2C3D4E5F6G7", "domain": "com", "results": [ { "position": 1, "asin": "B0CX23V2ZK", "title": "Anker Prime Power Bank (2026)", "link": "https://www.amazon.com/dp/B0CX23V2ZK", "image": "https://m.media-amazon.com/images/I/61new.jpg", "price": { "value": 129.99, "currency": "USD", "symbol": "$", "raw": "$129.99" }, "rating": 4.6, "ratings_total": 842, "is_prime": true, "availability": "In Stock" } ], "pagination": { "current_page": 1, "total_pages": 4, "total_results": 96 } } ``` Each seller products request costs **5 credits**. Failed requests are not charged. # Get Property Source: https://docs.scrapebadger.com/api-reference/endpoint/apartments/get-property GET /v1/apartments/property Full detail for one apartments.com property — floor plans, per-unit rent, beds, baths, square footage, availability, amenities, photos and office hours. ## Query Parameters Full apartments.com property URL, e.g. `https://www.apartments.com/urbane-kansas-city-mo/wcd6e5k/`. You can take this straight from a search result's `url`. There is also `GET /v1/apartments/properties/{slug}/{property_id}` if you would rather address the property by its parts — `slug` being the SEO segment (`urbane-kansas-city-mo`) and `property_id` the 7-character listing key (`wcd6e5k`). ## Response apartments.com listing key (nullable). The property URL that was fetched. Property name (nullable). Full address as rendered (nullable). City (nullable). Two-letter state code (nullable). ZIP code (nullable). Neighborhood, when the property lists one (nullable). Latitude (nullable). Longitude (nullable). Leasing phone number (nullable). Advertised range as rendered, e.g. `$1,288 - $5,412` (nullable). Low end of the advertised range (nullable). High end of the advertised range (nullable). Advertised bed range, e.g. `1 - 3 bd` (nullable). Property description (nullable). Amenity labels, deduplicated. Leasing-office hours as rendered. Gallery image URLs. Count of individually-listed units across all floor plans. Schools from the property's Schools section, as provided by GreatSchools. School name (nullable). Type as rendered, e.g. `Public Elementary School` (nullable). Whether the school sits under the page's Private Schools tab. Grade range, e.g. `PK-5`, `9-12` (nullable). Enrolled students (nullable). `Attendance Zone` (the property is zoned for this school) or `Nearby` (nullable). GreatSchools rating out of 10. **`null` means the school is unrated** — apartments.com renders no badge for those. It is never `0`. Always `10`. apartments.com's page for the school (nullable). The Schools section also lists nearby colleges and universities. Those are **not** returned as schools — they carry a drive time rather than a grade range. Floor-plan models. Plan name, e.g. `Axis` (nullable). Site-internal model key (nullable). Site-internal rental key (nullable). Bedrooms — `0.0` for a studio (nullable). Bathrooms (nullable). Price as rendered, e.g. `Starting at $1,288` (nullable). Low end for this plan (nullable). High end for this plan (nullable). The plan header verbatim — mixed content, not just size (nullable). Smallest square footage for this plan (nullable). Largest square footage for this plan (nullable). The individually-listed units for this plan. Count of units on this plan. `0` is normal on properties that advertise plans rather than individual units. Every unit across every floor plan, flattened — usually the shape you want. Unit label, e.g. `8625-2231` (nullable). Site-internal unit key (nullable). Site-internal rental key (nullable). The floor plan this unit belongs to (nullable). Bedrooms — `0.0` for a studio (nullable). Bathrooms (nullable). **The advertised monthly rent.** Use this one (nullable). The price column verbatim, so you can see qualifiers we did not parse (nullable). Raw `data-maxrent` from the site — roughly **2x** the advertised rent, apparently an upper bound across lease terms. Exposed unparsed; **do not use it as the rent** (nullable). Always `USD`. Square footage (nullable). Availability verbatim — `Now`, `Sep 3`. No year is rendered, so this is deliberately not a date (nullable). Floor-plan name for this unit (nullable). Photos attached to this unit. Videos attached to this unit. Floor-plan images attached to this unit. Virtual tours attached to this unit. Direct application URL, when the property offers one (nullable). **`rent` vs `max_term_rent`.** Both are on every unit. On a model advertised "Starting at $1,288", the units rendered `$1,298`while`data-maxrent`read`2876`— roughly double.`rent`is the advertised price;`max\_term\_rent\` is the raw attribute, exposed for completeness only. ## Example ```bash cURL theme={null} curl -H "X-API-Key: YOUR_KEY" \ "https://scrapebadger.com/v1/apartments/property?url=https%3A%2F%2Fwww.apartments.com%2Furbane-kansas-city-mo%2Fwcd6e5k%2F" ``` ```python Python theme={null} prop = await client.apartments.get_property( "https://www.apartments.com/urbane-kansas-city-mo/wcd6e5k/" ) for unit in prop.units: print(unit.unit_number, unit.rent, unit.beds, unit.sqft, unit.available_text) ``` ```typescript Node.js theme={null} const prop = await client.apartments.getProperty( "https://www.apartments.com/urbane-kansas-city-mo/wcd6e5k/", ); ``` **Cost:** 5 credits. # Search Listings Source: https://docs.scrapebadger.com/api-reference/endpoint/apartments/search-listings GET /v1/apartments/search Search apartments.com rental listings by location, with bedroom and price filters. Returns up to 40 property cards per page. ## Query Parameters The apartments.com location slug — the segment right after the domain in the site's own URLs. E.g. `kansas-city-mo`, `new-york-ny`, `austin-tx`, or a ZIP like `64108`. Page number, `1`-`28`. Each page holds up to 40 property cards. Bedroom count: `0` for studios, `1` to `4` for bedroom counts. Minimum monthly rent in USD (`100`-`20000`). Combine with `max_price` for a range. Maximum monthly rent in USD (`100`-`20000`). ## Response The location slug that was searched. The apartments.com URL that was fetched. Current page number. Total pages available for this query (nullable). Total matching properties as apartments.com reports them (nullable). Number of cards on this page (up to 40). The property cards. apartments.com listing key, e.g. `tbnk7t8` (nullable). Full property URL — pass this to the property endpoint for per-unit pricing (nullable). Property name (nullable). Full address as displayed (nullable). Street line only (nullable). ISO country code, always `US` (nullable). Leasing phone number (nullable). Rent/bed rollup rows as rendered, e.g. `[{"beds": "1 Bed", "price": "$1,559+"}]`. Kept as text because a card shows ranges and `+` qualifiers, not a single resolvable number. Lowest price parsed out of the rollup (nullable). First rollup row's bed label (nullable). Amenity labels shown on the card. Whether apartments.com flagged the card as a featured/promoted unit. A card is a **summary**. For per-unit rent, beds, baths, square footage and availability, pass its `url` to [Get Property](/api-reference/endpoint/apartments/get-property). ## Filter behaviour Filters are applied by apartments.com itself. Measured against live result counts on `kansas-city-mo` (700 unfiltered): `beds=1` → 374, `beds=2` → 490, `beds=0` → 145, `max_price=1500` → 646, `beds=1&max_price=1500` → 320. ## Example ```bash cURL theme={null} curl -H "X-API-Key: YOUR_KEY" \ "https://scrapebadger.com/v1/apartments/search?location=kansas-city-mo&beds=1&max_price=1500" ``` ```python Python theme={null} page = await client.apartments.search("kansas-city-mo", beds=1, max_price=1500) for card in page.results: print(card.name, card.address, card.pricing) ``` ```typescript Node.js theme={null} const page = await client.apartments.search("kansas-city-mo", { beds: 1, maxPrice: 1500 }); ``` **Cost:** 5 credits per page. # Top Charts Source: https://docs.scrapebadger.com/api-reference/endpoint/app-store/charts GET https://scrapebadger.com/v1/app-store/charts App Store top-free, top-paid and top-grossing charts for a storefront, optionally scoped to one genre. Top charts for a storefront, for iPhone or iPad, optionally scoped to a single genre. `rank` is the app's position in the feed — Apple sends no explicit rank field. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Storefront code, lowercase ISO 3166-1 alpha-2. See [`/markets`](/api-reference/endpoint/app-store/list-markets). `top-free`, `top-paid` or `top-grossing`. Genre id to scope the chart, e.g. `6014` (Games). Omit for the overall chart. Only ids from [`/genres`](/api-reference/endpoint/app-store/list-genres) are accepted — every one of them is verified to return a non-empty chart. Entries to return, `1`–`200`. `apps` (iPhone) or `ipad`. ## Response The chart type returned. `apps` or `ipad`. The genre scope, or `null` for the overall chart. Entries returned. 1-based chart position. Copyright line, when Apple sends one. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/app-store/charts?country=us&type=top-free&genre=6014&limit=50" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/app-store/charts?" + new URLSearchParams({ country: "us", type: "top-grossing", limit: "50" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { apps } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/app-store/charts", headers={"X-API-Key": "YOUR_API_KEY"}, params={"country": "us", "type": "top-free", "genre": 6014, "limit": 50}, ) chart = res.json()["apps"] ``` ```json Response theme={null} { "country": "us", "type": "top-free", "entity": "apps", "genre_id": 6014, "result_count": 50, "apps": [ { "rank": 1, "app_id": 1544098059, "name": "Block Blast!", "url": "https://apps.apple.com/us/app/block-blast/id1544098059", "developer_name": "Hungry Studio", "developer_url": "https://apps.apple.com/us/developer/hungry-studio/id1543997352", "icon_url": "https://is1-ssl.mzstatic.com/image/thumb/blockblast/100x100bb.png", "price": 0.0, "currency": "USD", "formatted_price": "Free", "genre": "Games", "genre_id": 6014, "summary": "A classic block puzzle game that is easy to learn.", "rights": "© 2026 Hungry Studio", "release_date_utc": 1610236800.0, "release_date_at": "2021-01-10T00:00:00Z" } ] } ``` ## Errors | Status | Meaning | | - | - | | `400` | Unknown chart type, entity, genre id, or malformed country. | | `429` | Apple is throttling — retry shortly. | | `502` | Unexpected upstream failure — **not billed**. | # Get App Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/app-store/get-app GET https://scrapebadger.com/v1/app-store/apps/{app_id} Full App Store app detail by track id or bundle id, enriched with the star histogram, in-app-purchase list, full-resolution screenshots and App Privacy label. Full detail for one app. Merges two sources: Apple's iTunes lookup (the core fields, always present) and the storefront product page (`extras`, best-effort — a storefront failure degrades the response rather than failing it). **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Numeric track id (e.g. `310633997`) **or** bundle id (e.g. `com.whatsapp`). A value containing a dot is treated as a bundle id. ## Query Parameters Storefront code, lowercase ISO 3166-1 alpha-2 — sets pricing, availability and the localised copy. Result language, e.g. `en_us`. Defaults to the storefront's. Fetch the storefront page for the rating histogram, in-app-purchase list, full-resolution screenshots and App Privacy detail. Set `false` to skip that second fetch when only the core iTunes fields are needed. ## Response Every field from [search](/api-reference/endpoint/app-store/search), plus: Storefront enrichment. `null` when `include_extras=false` or when the storefront fetch failed. `average`, `total`, `one_star` … `five_star`. Apple's storefront `total` can differ slightly from `rating_count` — the two are computed on different schedules, and both are surfaced rather than reconciled. `name`, `price` — the localised display price; Apple exposes no numeric/currency split on the page. `url`, `width`, `height` at native resolution. The storefront's copy of the description. App Privacy "nutrition label" groups — `identifier`, `title`, `detail`, `categories[]`. The page's raw Information rows (Seller, Size, Category, Compatibility, Languages, Age Rating, Copyright …) as a flat string map — Apple adds and renames rows per app type, so nothing is dropped. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/app-store/apps/310633997?country=us" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/app-store/apps/com.whatsapp?country=us", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const app = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/app-store/apps/310633997", headers={"X-API-Key": "YOUR_API_KEY"}, params={"country": "us", "include_extras": "true"}, ) app = res.json() ``` ```json Response theme={null} { "app_id": 310633997, "bundle_id": "net.whatsapp.WhatsApp", "name": "WhatsApp Messenger", "kind": "software", "url": "https://apps.apple.com/us/app/whatsapp-messenger/id310633997", "developer_id": 310634000, "developer_name": "WhatsApp Inc.", "seller_name": "WhatsApp Inc.", "price": 0.0, "currency": "USD", "formatted_price": "Free", "rating": 4.7, "rating_count": 15216441, "rating_current_version": 4.7, "rating_count_current_version": 21883, "description": "WhatsApp from Meta is a FREE messaging and video calling app...", "release_notes": "Bug fixes and performance improvements.", "version": "26.16.72", "minimum_os_version": "15.1", "file_size_bytes": 246718464, "content_rating": "12+", "advisories": ["Infrequent/Mild Profanity or Crude Humor"], "genres": ["Social Networking", "Utilities"], "genre_ids": [6005, 6002], "primary_genre": "Social Networking", "primary_genre_id": 6005, "language_codes": ["EN", "DE", "ES", "FR", "PT"], "icon_url": "https://is1-ssl.mzstatic.com/image/thumb/example/512x512bb.jpg", "screenshot_urls": ["https://is1-ssl.mzstatic.com/image/thumb/shot1/392x696bb.png"], "release_date_utc": 1241740800.0, "release_date_at": "2009-05-08T00:00:00Z", "current_version_release_date_utc": 1754870400.0, "current_version_release_date_at": "2026-08-11T00:00:00Z", "extras": { "rating_histogram": { "average": 4.7, "total": 15216441, "one_star": 486926, "two_star": 152164, "three_star": 304328, "four_star": 1673808, "five_star": 12599215 }, "has_in_app_purchases": false, "in_app_purchases": [], "iphone_screenshots": [ { "url": "https://is1-ssl.mzstatic.com/image/thumb/shot1/1290x2796bb.png", "width": 1290, "height": 2796 } ], "ipad_screenshots": [], "whats_new": "Bug fixes and performance improvements.", "whats_new_version": "26.16.72", "chart_position": 4, "chart_category": "Social Networking", "is_editors_choice": false, "privacy_types": [ { "identifier": "DATA_LINKED_TO_YOU", "title": "Data Linked to You", "detail": "The following data, which may be collected and linked to your identity, may be used for the following purposes:", "categories": ["Contact Info", "User Content", "Identifiers", "Usage Data", "Diagnostics"] } ], "information": { "Seller": "WhatsApp Inc.", "Size": "235.3 MB", "Category": "Social Networking", "Compatibility": "iPhone — Requires iOS 15.1 or later.", "Languages": "English and 59 more", "Age Rating": "12+", "Copyright": "© 2026 WhatsApp LLC" } } } ``` A **numeric id** runs both fetches concurrently, so enrichment usually costs no extra latency. A **bundle id** costs one extra round trip: the storefront page is addressable by numeric id only, so the lookup has to resolve first. ## Errors | Status | Meaning | | - | - | | `400` | Malformed country code. | | `404` | No such app in that storefront (Apple answers `200` with an empty result; the absence is detected so you are not billed for an empty success). | | `429` | Apple is throttling — retry shortly. | | `502` | Unexpected upstream failure — **not billed**. | # Get Developer Apps Source: https://docs.scrapebadger.com/api-reference/endpoint/app-store/get-developer GET https://scrapebadger.com/v1/app-store/developers/{developer_id} An App Store developer and every app they publish in a storefront. A developer and their catalogue in one call — Apple mixes a single `artist` entry in with the `software` entries, and this route splits them. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Numeric artist id, e.g. `284882218`. Take it from `developer_id` on any app record. Non-numeric values are rejected with `400`. ## Query Parameters Storefront code, lowercase ISO 3166-1 alpha-2. Apps to return, `1`–`200`. ## Response Apple's artist type, e.g. `software`. Apps returned. The developer's apps — same shape as [search results](/api-reference/endpoint/app-store/search). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/app-store/developers/284882218?country=us&limit=50" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/app-store/developers/284882218?" + new URLSearchParams({ country: "us", limit: "50" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { developer, apps } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/app-store/developers/284882218", headers={"X-API-Key": "YOUR_API_KEY"}, params={"country": "us", "limit": 50}, ) data = res.json() ``` ```json Response theme={null} { "country": "us", "developer": { "developer_id": 284882218, "name": "Meta Platforms, Inc.", "developer_type": "software", "url": "https://apps.apple.com/us/developer/meta-platforms-inc/id284882218" }, "result_count": 9, "apps": [ { "app_id": 284882215, "bundle_id": "com.facebook.Facebook", "name": "Facebook", "url": "https://apps.apple.com/us/app/facebook/id284882215", "developer_id": 284882218, "developer_name": "Meta Platforms, Inc.", "price": 0.0, "currency": "USD", "formatted_price": "Free", "rating": 4.1, "rating_count": 15602118, "version": "526.0", "minimum_os_version": "15.1", "file_size_bytes": 358612992, "content_rating": "12+", "genres": ["Social Networking"], "genre_ids": [6005], "icon_url": "https://is1-ssl.mzstatic.com/image/thumb/facebook/512x512bb.jpg", "current_version_release_date_at": "2026-08-10T00:00:00Z" } ] } ``` ## Errors | Status | Meaning | | - | - | | `400` | Non-numeric developer id, or malformed country. | | `404` | No such developer in that storefront. | | `429` | Apple is throttling — retry shortly. | # Get App Reviews Source: https://docs.scrapebadger.com/api-reference/endpoint/app-store/get-reviews GET https://scrapebadger.com/v1/app-store/apps/{app_id}/reviews Customer reviews for an App Store app — 50 per page, pages 1-10, most recent or most helpful. Customer reviews for an app — 50 per page, pages 1 to 10, per storefront. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters **Numeric** track id, e.g. `310633997`. Apple's review feed has no bundle-id form — a bundle id here returns `400`. Resolve it through [`/apps/{bundle_id}`](/api-reference/endpoint/app-store/get-app) and use the `app_id` from that response. ## Query Parameters Storefront code, lowercase ISO 3166-1 alpha-2. Page number, `1`–`10`. Apple hard-rejects page 11+, so the ceiling is enforced here with a clear error instead of an upstream failure. `mostRecent` or `mostHelpful`. ## Response Storefront the reviews came from. Reviews in this page. `1`–`5`. App version reviewed. Net helpful votes. Total votes cast. Unix seconds. ISO 8601 UTC. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/app-store/apps/310633997/reviews?country=us&page=1&sort=mostRecent" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/app-store/apps/310633997/reviews?" + new URLSearchParams({ country: "us", page: "1", sort: "mostHelpful" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { reviews } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/app-store/apps/310633997/reviews", headers={"X-API-Key": "YOUR_API_KEY"}, params={"country": "us", "page": 1, "sort": "mostRecent"}, ) reviews = res.json()["reviews"] ``` ```json Response theme={null} { "app_id": "310633997", "country": "us", "page": 1, "sort": "mostRecent", "result_count": 50, "reviews": [ { "review_id": "11284763055", "user_name": "dana_in_dc", "user_url": "https://itunes.apple.com/us/reviews?userProfileId=1043201991", "title": "Rock solid for international calls", "content": "Voice quality is consistently better than anything else I've tried abroad.", "rating": 5, "version": "26.16.72", "vote_sum": 12, "vote_count": 14, "updated_utc": 1754956800.0, "updated_at": "2026-08-12T00:00:00Z" } ] } ``` Reviews are **per-storefront**: the `us` and `de` feeds for one app are different review sets, not translations of one set. Sweep the storefronts you care about rather than assuming `us` covers them. ## Errors | Status | Meaning | | - | - | | `400` | Non-numeric app id, page above 10, unknown sort, or malformed country. | | `404` | No review feed for that app in that storefront. | | `429` | Apple is throttling — retry shortly. | # List Genres Source: https://docs.scrapebadger.com/api-reference/endpoint/app-store/list-genres GET https://scrapebadger.com/v1/app-store/genres App Store genre ids for use with /charts?genre=. Free. App Store genre ids, for use with [`/charts?genre=`](/api-reference/endpoint/app-store/charts). Static reference data, so this endpoint is **free**. **Credits:** 0 Every id listed is verified to return a **non-empty chart**. Four ids Apple still documents are deliberately absent because their feeds come back empty — Catalogs (6022), Stickers (6025), Games/Dice (7007) and Games/Educational (7008). They can still appear in an app's own `genre_ids`; they just cannot be charted. ## Authorization Your ScrapeBadger API key. ## Response Genres returned (40). e.g. `6014`. e.g. `Games` or `Games/Puzzle`. Set on Games subgenres (`6014`); `null` otherwise. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/app-store/genres" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch("https://scrapebadger.com/v1/app-store/genres", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY }, }); const { genres } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/app-store/genres", headers={"X-API-Key": "YOUR_API_KEY"}, ) genres = res.json()["genres"] ``` ```json Response theme={null} { "result_count": 40, "genres": [ { "genre_id": 6000, "name": "Business", "parent_id": null }, { "genre_id": 6005, "name": "Social Networking", "parent_id": null }, { "genre_id": 6007, "name": "Productivity", "parent_id": null }, { "genre_id": 6014, "name": "Games", "parent_id": null }, { "genre_id": 7012, "name": "Games/Puzzle", "parent_id": 6014 } ] } ``` # List Markets Source: https://docs.scrapebadger.com/api-reference/endpoint/app-store/list-markets GET https://scrapebadger.com/v1/app-store/markets Supported App Store storefronts. Free. Supported App Store storefronts — the values every `country` parameter accepts. Static reference data, so this endpoint is **free**. **Credits:** 0 Informational: the routes accept **any well-formed 2-letter code** and let Apple arbitrate, so a storefront missing from this list still works. ## Authorization Your ScrapeBadger API key. ## Response Storefronts returned (170). Lowercase ISO 3166-1 alpha-2, e.g. `us`. e.g. `United States`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/app-store/markets" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch("https://scrapebadger.com/v1/app-store/markets", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY }, }); const { markets } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/app-store/markets", headers={"X-API-Key": "YOUR_API_KEY"}, ) markets = res.json()["markets"] ``` ```json Response theme={null} { "result_count": 170, "markets": [ { "code": "us", "name": "United States" }, { "code": "gb", "name": "United Kingdom" }, { "code": "de", "name": "Germany" }, { "code": "jp", "name": "Japan" }, { "code": "br", "name": "Brazil" } ] } ``` # Search Apps Source: https://docs.scrapebadger.com/api-reference/endpoint/app-store/search GET https://scrapebadger.com/v1/app-store/search Full-text search across the App Store — every hit carries the complete iTunes record, not a thin card. Full-text search across the App Store. Every hit carries the same \~40 fields the detail endpoint returns, so a search result rarely needs a follow-up lookup. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search term, e.g. `slack`. Storefront code, lowercase ISO 3166-1 alpha-2. See [`/markets`](/api-reference/endpoint/app-store/list-markets). Which catalogue to search: `software` (iPhone), `iPadSoftware` or `macSoftware`. These are **separate catalogues, not filters** — a Mac-only app is absent from `software` entirely. Results to return, `1`–`200`. Results to skip, `0`–`199`. Applied by this service, not by Apple — the Search API `403`s its own `offset` parameter, so paging is a slice of one 200-result response and `offset + limit` is capped at 200. Result language, e.g. `en_us` or `de_de`. Defaults to the storefront's. ## Response Echo of the requested term. Storefront searched. Catalogue searched. Apps returned in this page. Matching apps, in Apple's relevance order. Same shape as [app detail](/api-reference/endpoint/app-store/get-app) minus `extras`. Numeric track id, e.g. `618783545`. e.g. `com.tinyspeck.chatlyio`. e.g. `Free`. Average rating, all versions. ISO 8601 UTC (with `release_date_utc`). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/app-store/search?query=slack&country=us&limit=25" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/app-store/search?" + new URLSearchParams({ query: "slack", country: "us", limit: "25" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { apps } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/app-store/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "slack", "country": "us", "limit": 25}, ) apps = res.json()["apps"] ``` ```json Response theme={null} { "query": "slack", "country": "us", "entity": "software", "result_count": 25, "apps": [ { "app_id": 618783545, "bundle_id": "com.tinyspeck.chatlyio", "name": "Slack", "kind": "software", "url": "https://apps.apple.com/us/app/slack/id618783545", "developer_id": 618783544, "developer_name": "Slack Technologies, Inc.", "developer_url": "https://apps.apple.com/us/developer/slack-technologies-inc/id618783544", "seller_name": "Slack Technologies, Inc.", "price": 0.0, "currency": "USD", "formatted_price": "Free", "rating": 4.8, "rating_count": 216114, "rating_current_version": 4.8, "rating_count_current_version": 3891, "description": "Slack brings team communication and collaboration into one place...", "release_notes": "We fixed a handful of bugs to keep things running smoothly.", "version": "26.08.10", "minimum_os_version": "16.0", "file_size_bytes": 194837504, "content_rating": "4+", "advisories": [], "genres": ["Business", "Productivity"], "genre_ids": [6000, 6007], "primary_genre": "Business", "primary_genre_id": 6000, "language_codes": ["EN", "DE", "FR", "JA"], "icon_url": "https://is1-ssl.mzstatic.com/image/thumb/example/512x512bb.jpg", "screenshot_urls": ["https://is1-ssl.mzstatic.com/image/thumb/shot1/392x696bb.png"], "release_date_utc": 1367280000.0, "release_date_at": "2013-04-30T00:00:00Z", "current_version_release_date_utc": 1754870400.0, "current_version_release_date_at": "2026-08-11T00:00:00Z", "extras": null } ] } ``` Apple caps this catalogue at **200 results per query** and offers no deep paging. `offset + limit` above 200 returns fewer results rather than an error. # Baidu Autocomplete Source: https://docs.scrapebadger.com/api-reference/endpoint/baidu/autocomplete GET https://scrapebadger.com/v1/baidu/autocomplete Baidu search-box suggestions for a partial term — the cheapest call in the Baidu API at 1 credit. Baidu's search-box suggestions for a partial term — what the dropdown on `baidu.com` would show as you type. At **1 credit** this is the cheapest call in the Baidu API and the fastest way to turn a seed term into real Chinese queries people actually search. **Credits:** 1 ## Authorization Your ScrapeBadger API key. ## Query Parameters Partial search term, e.g. `咖啡` or `coff`. URL-encode as UTF-8. ## Response Echo of the partial term. Baidu's suggestions, in Baidu's own order (most likely first). The suggested query. Baidu's suggestion type, e.g. `sug`. `null` when Baidu omits it. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/baidu/autocomplete?query=%E5%92%96%E5%95%A1" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/baidu/autocomplete?" + new URLSearchParams({ query: "咖啡" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/baidu/autocomplete", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "咖啡"}, ) data = res.json() ``` ```json Response theme={null} { "query": "咖啡", "suggestions": [ { "query": "咖啡品牌排行榜", "type": "sug" }, { "query": "咖啡机", "type": "sug" }, { "query": "咖啡品牌", "type": "sug" }, { "query": "咖啡豆", "type": "sug" }, { "query": "咖啡斑", "type": "sug" } ] } ``` ## Keyword expansion Autocomplete is the cheap half of a two-step keyword workflow: 1. Call `/autocomplete` on the seed term (1 credit) to get Baidu's real query variants. 2. Call [`/search`](/api-reference/endpoint/baidu/search) on each variant (5 credits) and merge results on `url`. That covers a topic far more broadly than paging one query toward its page-76 wall, for fewer credits. The `related_searches` block on every `/search` response feeds the same loop for free. Suggestions are **prefix-driven**, so the seed's ending changes the whole set: `咖啡` returns brand and bean queries, while `咖啡机` returns machine queries. Fan out over a few seeds rather than trusting one. Latin input works — `coff` returns suggestions — but Baidu's suggestion index is overwhelmingly Chinese, so Chinese seeds return far more. ## Errors | Status | Meaning | | - | - | | `422` | Anti-bot challenge — **not billed**. Retry; it succeeds. | | `502` | Baidu's suggestion API returned an unparseable payload. Retry. | # Baidu Image Search Source: https://docs.scrapebadger.com/api-reference/endpoint/baidu/images GET https://scrapebadger.com/v1/baidu/images Search Baidu images — full-size image URLs, Baidu-hosted thumbnail copies, pixel dimensions, format and the source page each image came from. Search Baidu images. Each result carries the **full-size image URL** (Baidu's decoded `objURL`), three Baidu-hosted copies at different sizes, the real pixel dimensions, the file format, and the page the image was found on. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `猫`. URL-encode as UTF-8. Result page, `1`–`50`. Fixed at **30 images per page** — Baidu's own page size, not adjustable. ## Response Echo of the requested query. The page returned. Baidu's own reported total for the query. Images on this page (up to 30). 1-based rank on the page. Image title / caption. **Full-size image URL** on the origin host, decoded from Baidu's obfuscated `objURL`. Baidu-hosted thumbnail copy. Baidu-hosted mid-size copy. Baidu-hosted hover-preview copy. Full-size image width in pixels. Full-size image height in pixels. Image format, e.g. `jpg`. Page the image was found on. Title of the page the image was found on. Only `position`, `query` and `page` are guaranteed present — including `title`, which Baidu omits on some tiles. Every other field is nullable. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/baidu/images?query=%E7%8C%AB" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/baidu/images?" + new URLSearchParams({ query: "猫" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/baidu/images", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "猫"}, ) data = res.json() ``` ```json Response theme={null} { "query": "猫", "page": 1, "total_results": 748836, "results": [ { "position": 1, "title": "白杯,咖啡,咖啡豆 4k", "image_url": "https://s2.best-wallpaper.net/wallpaper/iphone/1708/White-cup-coffee-coffee-beans_iphone_640x1136.jpg", "thumbnail_url": "https://img0.baidu.com/it/u=1467163901,1497482106&fm=253&fmt=auto&app=138&f=JPEG?w=282&h=500", "middle_url": "https://img0.baidu.com/it/u=1467163901,1497482106&fm=253&fmt=auto&app=138&f=JPEG?w=282&h=500", "hover_url": "https://img0.baidu.com/it/u=1467163901,1497482106&fm=253&fmt=auto&app=138&f=JPEG?w=282&h=500", "width": 640, "height": 1136, "type": "jpg", "from_url": "http://cn.best-wallpaper.net/white-cup-coffee-coffee-beans_wallpapers.html", "from_title": "白杯,咖啡,咖啡豆 4k" }, { "position": 2, "title": "时光里的咖啡记忆 #咖啡 #拿铁 - 抖音", "image_url": "https://p3-pc-sign.douyinpic.com/tos-cn-i-0813c000-ce/oIf4pFOAEQFIwUojvFf8aAUA9ACTnDezEAqxEq~tplv-dy-aweme-images:q75.webp", "thumbnail_url": "https://img2.baidu.com/it/u=2072998656,274351222&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1067", "middle_url": "https://img2.baidu.com/it/u=2072998656,274351222&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1067", "hover_url": "https://img2.baidu.com/it/u=2072998656,274351222&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1067", "width": 1080, "height": 1440, "type": "jpg", "from_url": "http://www.douyin.com/note/7467811736117087545", "from_title": "时光里的咖啡记忆 #咖啡 #拿铁 - 抖音" } ] } ``` ## Which URL to use | Field | Host | Use it for | | - | - | - | | `image_url` | The origin site | Downloading the real asset at full resolution. | | `thumbnail_url` / `middle_url` / `hover_url` | `img*.baidu.com` | Grids and previews — Baidu's CDN is fast and does not hotlink-block. | `image_url` points at a third-party host, so it can 404, hotlink-block, or redirect — Baidu's index outlives the pages it indexed. Fall back to `thumbnail_url` when a fetch of `image_url` fails, and treat `width`/`height` as describing the original asset, not the Baidu-hosted copies. `type` is Baidu's declared format and is frequently `jpg` even for a `.webp` asset. Sniff the bytes if the real format matters. ## Errors | Status | Meaning | | - | - | | `422` | Anti-bot challenge — **not billed**. Retry; it succeeds. | | `502` | Baidu's image JSON API returned an unparseable payload. Retry. | # Baidu News Source: https://docs.scrapebadger.com/api-reference/endpoint/baidu/news GET https://scrapebadger.com/v1/baidu/news Search Baidu's news vertical — articles with publisher, publish date and the real article URL, ordered by relevance or recency. Search Baidu's news vertical. Articles carry the publisher name, the publish date in both Baidu's raw form and ISO 8601, and the **real article URL** — not a `baidu.com` redirect. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `人工智能`. URL-encode as UTF-8. Result page, `1`–`76`. Fixed at 10 articles per page — the news vertical has no page-size parameter. Result ordering. `relevance` (Baidu's default ranking) or `time` (most recent first). ## Response Echo of the requested query. The page returned. Baidu's own reported total, when it renders one. `null` otherwise. The baidu.com URL that was fetched. Articles on this page. 1-based rank on the page. Article headline. The **real article URL**. Baidu's tracking redirect, when the article carries one. Article excerpt. Publisher name, e.g. `新华网`, `微信公众平台`. Baidu's own date string, e.g. `2026年8月1日` or `3小时前`. ISO 8601 date (`YYYY-MM-DD`), set only when `date` is unambiguous. Article image URL, when present. Only `position`, `title`, `query` and `page` are guaranteed present. Every other field is nullable — Baidu's news cards vary by publisher. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/baidu/news?query=%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD&sort=time" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/baidu/news?" + new URLSearchParams({ query: "人工智能", sort: "time" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/baidu/news", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "人工智能", "sort": "time"}, ) data = res.json() ``` ```json Response theme={null} { "query": "人工智能", "page": 1, "total_results": null, "results": [ { "position": 1, "title": "以科学了解咖啡的秘密", "url": "http://www.jgj.moa.gov.cn/kptd/202012/t20201207_6357680.htm", "baidu_url": null, "snippet": "咖啡是用经过烘焙的咖啡豆制作冲泡的饮料,与可可、茶并称为世界三大饮料,是流行于世界的主要饮品。", "source": "农产品质量安全监管司", "date": "2020年12月25日", "date_at": "2020-12-25", "thumbnail": null }, { "position": 2, "title": "咖啡知识 | 咖啡知识大全", "url": "https://mp.weixin.qq.com/s?__biz=MzA5MzI2MzYyMQ==&mid=2247503901&idx=5", "baidu_url": null, "snippet": "豆是咖啡树果实中的种子,它们会经过采摘、干燥、烘焙等处理过程,最终被磨成粉用于冲泡咖啡...", "source": "微信公众平台", "date": "2024年8月15日", "date_at": "2024-08-15", "thumbnail": "https://t9.baidu.com/it/u=546988488,560360434&fm=217&app=126" } ], "url": "https://www.baidu.com/s?tn=news&word=%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD&ie=utf-8" } ``` ## Sorting for monitoring For a news monitor, poll with `sort=time` and stop at the first article you have already seen. Deduplicate on `url` (the real article URL), **not** on `title` — Chinese outlets syndicate the same headline across many domains, and on `baidu_url`, which is per-impression and changes between requests. `sort=time` orders by Baidu's own index date. Freshly indexed older articles can appear above newer ones, so `date_at` is the field to trust when you need a real chronology. ## Errors | Status | Meaning | | - | - | | `422` | Anti-bot challenge — **not billed**. Retry; it succeeds. | | `502` | Baidu returned a page without the result container. Retry. | # Baidu Web Search Source: https://docs.scrapebadger.com/api-reference/endpoint/baidu/search GET https://scrapebadger.com/v1/baidu/search Search baidu.com — organic results with the real target URL, related searches, language and publish-date filters. Search `baidu.com` — the web SERP of China's #1 search engine. Every organic result carries the **real target URL** in `url` (decoded from Baidu's `mu` attribute), alongside the `baidu.com/link?url=` tracking redirect in `baidu_url`. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `咖啡机` or `coffee machine`. URL-encode as UTF-8. Result page, `1`–`76`. Baidu's SERP stops serving past \~76 pages regardless of the total it reports — see [Pagination](#pagination). Results per page, `1`–`50` (Baidu's own cap). The page offset is `(page - 1) * num`, so keep `num` fixed across a crawl of one query. Restrict result language. One of `all`, `zh-cn` (simplified Chinese), `zh-tw` (traditional Chinese) — Baidu's only three language codes. Unix timestamp — only results published **after** this. Unix timestamp — only results published **before** this. Pass either bound alone; the other end of the window defaults to open. ## Response Echo of the requested query. The page returned. Results per page that was requested. **Baidu's own claim**, parsed from `百度为您找到相关结果约N个` — not a reachable count. Useful as a *relative* signal only. `null` when Baidu omits the line. The baidu.com URL that was fetched. Organic results on this page. 1-based rank on the page. Result title text. The **real target URL**, decoded from the result's `mu` attribute. Baidu's `baidu.com/link?url=...` tracking redirect. The URL as displayed on the result, when Baidu shows one. Result description text. Site name shown on the result, e.g. `阿里巴巴1688`. Baidu's own date string, e.g. `2026年7月27日` or `3天前`. ISO 8601 date (`YYYY-MM-DD`), set only when `date` is unambiguous. Thumbnail image URL, when the result carries one. Baidu's result template id, e.g. `se_com_default`, `www_index`. Baidu's query suggestions from the foot of the SERP. The suggested query. Baidu SERP URL for the suggestion. Only `position`, `title`, `query`, `page`, `num` and `url` are guaranteed present. Every other field is nullable — Baidu's SERP renders a different field set per result template (`tpl`). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/baidu/search?query=%E5%92%96%E5%95%A1%E6%9C%BA&num=20&language=zh-cn" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/baidu/search?" + new URLSearchParams({ query: "咖啡机", num: "20", language: "zh-cn", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/baidu/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "咖啡机", "num": 20, "language": "zh-cn"}, ) data = res.json() ``` ```json Response theme={null} { "query": "咖啡机", "page": 1, "num": 10, "total_results": 4820000, "results": [ { "position": 1, "title": "专业咖啡机价格-最新专业咖啡机价格、批发报价、价格大全 - 阿里巴巴", "url": "https://www.1688.com/jiage/-D7A8D2B5BFA7B7C8BBFA.html", "baidu_url": "http://www.baidu.com/link?url=m4_ZyR-m51ZWH--9M5Fnrzn4W0NebuakZ7fPd1qIt2l", "display_url": null, "snippet": "阿里巴巴为您找到2,955个今日最新的专业咖啡机价格,专业咖啡机批发价格等行情走势,您还可以找磨咖啡机,...", "source": "阿里巴巴1688", "date": "2026年7月27日", "date_at": "2026-07-27", "thumbnail": "https://t9.baidu.com/it/u=1053246899,2367519289&fm=217&app=126", "tpl": "www_index" }, { "position": 2, "title": "高压咖啡机价格-最新高压咖啡机价格、批发报价、价格大全 - 阿里巴巴", "url": "https://www.1688.com/jiage/-B8DFD1B9BFA7B7C8BBFA.html", "baidu_url": "http://www.baidu.com/link?url=m4_ZyR-m51ZWH--9M5Fnrzn4W0NebuakZ7fPd1qIt2lDSNc", "display_url": null, "snippet": "阿里巴巴为您找到3,770个今日最新的高压咖啡机价格,高压咖啡机批发价格等行情走势,您还可以找市场价格、...", "source": "阿里巴巴1688", "date": "2026年7月25日", "date_at": "2026-07-25", "thumbnail": "https://t9.baidu.com/it/u=303549370,1074137836&fm=217&app=126", "tpl": "www_index" } ], "related_searches": [ { "query": "咖啡机器人多少钱一台", "url": "https://www.baidu.com/s?wd=%E5%92%96%E5%95%A1%E6%9C%BA%E5%99%A8%E4%BA%BA%E5%A4%9A%E5%B0%91%E9%92%B1%E4%B8%80%E5%8F%B0&tn=baidu" }, { "query": "咖啡机全自动研磨一体", "url": "https://www.baidu.com/s?wd=%E5%92%96%E5%95%A1%E6%9C%BA%E5%85%A8%E8%87%AA%E5%8A%A8%E7%A0%94%E7%A3%A8%E4%B8%80%E4%BD%93&tn=baidu" }, { "query": "咖啡机厂家", "url": "https://www.baidu.com/s?wd=%E5%92%96%E5%95%A1%E6%9C%BA%E5%8E%82%E5%AE%B6&tn=baidu" } ], "url": "https://www.baidu.com/s?wd=%E5%92%96%E5%95%A1%E6%9C%BA&ie=utf-8" } ``` ## Pagination `total_results` is not reachable. Baidu's SERP dries up past roughly **page 76**, so `page` is clamped to `1`–`76` — a request beyond the wall is rejected rather than billed for an empty page. The page offset is `(page - 1) * num`. Raising `num` is therefore the cheaper route to depth than raising `page`: `num=50` reaches 500 results in **10 calls** instead of 50. Keep `num` fixed for the whole crawl of one query — changing it mid-crawl shifts the offset window and re-serves rows you already have. To go wider than one query's wall, expand the seed rather than paging deeper: feed `related_searches` (free, already in this response) and [`/autocomplete`](/api-reference/endpoint/baidu/autocomplete) (1 credit) back in as new queries, then merge results on `url`. ## Date filtering `time_from` / `time_to` are Unix timestamps and map onto Baidu's own `gpc` filter. Either bound may be passed alone — the open end defaults to `0` (from) or now (to). ```bash theme={null} # Results published in the last 7 days curl "https://scrapebadger.com/v1/baidu/search?query=%E5%92%96%E5%95%A1%E6%9C%BA&time_from=$(($(date +%s) - 604800))" \ -H "X-API-Key: YOUR_API_KEY" ``` Baidu filters on **its own idea** of a page's publish date, which is not always the date rendered in `date`. Treat the window as a filter on Baidu's index, not a guarantee about the page. ## Errors | Status | Meaning | | - | - | | `422` | Anti-bot challenge — **not billed**. Retry; it succeeds. | | `502` | Baidu returned a page without the result container. Retry. | # Autocomplete Source: https://docs.scrapebadger.com/api-reference/endpoint/bing/autocomplete GET https://scrapebadger.com/v1/bing/autocomplete Get Bing search-box query suggestions for a partial term. Get Bing's search-box suggestions for a partial term. The cheapest call in this API — useful for expanding a seed keyword into real Bing queries before running [`/search`](/api-reference/endpoint/bing/search) on each one. **Credits:** 1 ## Authorization Your ScrapeBadger API key. ## Query Parameters Partial search term, e.g. `coff`. Bing market code, e.g. `en-US`. Suggestions are market-specific. See [`/markets`](/api-reference/endpoint/bing/list-markets). ## Response Echo of the requested term. The market the suggestions were fetched for. Number of suggestions. Suggested queries, in Bing's order. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/bing/autocomplete?query=coff" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/bing/autocomplete?" + new URLSearchParams({ query: "coff" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { suggestions } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/bing/autocomplete", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "coff"}, ) suggestions = res.json()["suggestions"] ``` ```json Response theme={null} { "query": "coff", "market": "en-US", "result_count": 8, "suggestions": [ "coffee", "coffee maker", "coffee near me", "coffee shop", "coffee table", "coffee grinder", "coffee machine", "coffee beans" ] } ``` # Image Search Source: https://docs.scrapebadger.com/api-reference/endpoint/bing/images GET https://scrapebadger.com/v1/bing/images Search Bing Images — full-size URL, thumbnail, source page and pixel dimensions per result. Search Bing Images. Each result carries the **full-size image URL**, a Bing thumbnail, the page the image lives on, and its pixel dimensions. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `golden retriever`. Bing market code, e.g. `en-US`. See [`/markets`](/api-reference/endpoint/bing/list-markets). Results to return. One of `off`, `moderate`, `strict`. ## Response Echo of the requested query. The market the results were fetched for. Images returned. Image results. 1-based rank. Full-size image URL. Bing-hosted thumbnail URL. The page the image lives on. Full-size width in pixels. Full-size height in pixels. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/bing/images?query=golden+retriever&count=10" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/bing/images?" + new URLSearchParams({ query: "golden retriever", count: "10" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/bing/images", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "golden retriever", "count": 10}, ) data = res.json() ``` ```json Response theme={null} { "query": "golden retriever", "market": "en-US", "result_count": 10, "results": [ { "position": 1, "title": "Golden Retriever Dog Breed Information", "image_url": "https://www.akc.org/wp-content/uploads/2017/11/Golden-Retriever.jpg", "thumbnail_url": "https://tse1.mm.bing.net/th?id=OIP.abc123", "source_url": "https://www.akc.org/dog-breeds/golden-retriever/", "source_domain": "akc.org", "width": 1920, "height": 1080 } ] } ``` # List Markets Source: https://docs.scrapebadger.com/api-reference/endpoint/bing/list-markets GET https://scrapebadger.com/v1/bing/markets List the curated Bing market codes. Free. List the curated Bing market codes. This endpoint is **free**. **Credits:** 0 There are no per-country Bing domains — every market is served from `www.bing.com`. The `market` code (`language-COUNTRY`) sets the result language and country ranking. **Any well-formed `mkt` value is accepted** by the search endpoints; this list is the curated reference set of 30 codes, which also drives exit-IP geo-targeting. ## Authorization Your ScrapeBadger API key. ## Response Number of markets. Curated markets. Bing market code, e.g. `en-US`. e.g. `United States`. Two-letter country code, e.g. `US`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/bing/markets" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch("https://scrapebadger.com/v1/bing/markets", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY }, }); const { markets } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/bing/markets", headers={"X-API-Key": "YOUR_API_KEY"}, ) markets = res.json()["markets"] ``` ```json Response theme={null} { "result_count": 30, "markets": [ { "code": "en-US", "name": "United States", "country": "US" }, { "code": "en-GB", "name": "United Kingdom", "country": "GB" }, { "code": "de-DE", "name": "Germany", "country": "DE" }, { "code": "fr-FR", "name": "France", "country": "FR" }, { "code": "ja-JP", "name": "Japan", "country": "JP" } ] } ``` # News Search Source: https://docs.scrapebadger.com/api-reference/endpoint/bing/news GET https://scrapebadger.com/v1/bing/news Search Bing News — headline, source, snippet and absolute publish time per article, with a freshness filter. Search Bing News. Parsed from **Bing's RSS feed** rather than the HTML news cards — that is why every article carries an absolute publish time (`published_at` ISO 8601 plus `published_utc` Unix) instead of a relative "2 hours ago", and why the schema is stable. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `interest rates`. Bing market code, e.g. `en-US`. See [`/markets`](/api-reference/endpoint/bing/list-markets). Restrict to recent articles. One of `day`, `week`, `month`. ## Response Echo of the requested query. The market the results were fetched for. Articles returned. News articles. 1-based rank. Destination article URL — Bing's redirect is resolved. Publisher name. Raw RFC-822 publish date from Bing. ISO 8601 UTC publish time. Unix publish timestamp. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/bing/news?query=interest+rates&freshness=week" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/bing/news?" + new URLSearchParams({ query: "interest rates", freshness: "week" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/bing/news", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "interest rates", "freshness": "week"}, ) data = res.json() ``` ```json Response theme={null} { "query": "interest rates", "market": "en-US", "result_count": 10, "results": [ { "position": 1, "title": "Fed Holds Rates Steady as Inflation Cools", "url": "https://www.reuters.com/markets/us/fed-holds-rates-steady", "source": "Reuters", "snippet": "The Federal Reserve kept its benchmark interest rate unchanged...", "published": "Fri, 07 Aug 2026 14:03:00 GMT", "published_at": "2026-08-07T14:03:00+00:00", "published_utc": 1786197780.0 } ] } ``` Because articles come from the RSS feed, thumbnails/imagery are not included — the trade for absolute dates and a stable schema. # Web Search Source: https://docs.scrapebadger.com/api-reference/endpoint/bing/search GET https://scrapebadger.com/v1/bing/search Search the Bing web SERP — organic results, ads, related searches and the reported total match count. Search Bing's web SERP. Organic results carry the **resolved destination URL** (Bing's `/ck/a` tracking redirects are decoded), display URL, site name, snippet and deep links. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `coffee machine`. Bing market code (`language-COUNTRY`), e.g. `en-US`, `de-DE`. See [`/markets`](/api-reference/endpoint/bing/list-markets). Results per page, `1`–`50`. An upper bound, not a guarantee — see [Result depth](#result-depth). Zero-based result offset for pagination. One of `off`, `moderate`, `strict`. ## Response Echo of the requested query. The market the results were fetched for. Bing's reported total match count (approximate), e.g. `59300`. The count as displayed, e.g. `About 59,300 results`. Organic results returned in this response. Organic results. 1-based rank within this page. Destination URL — the `/ck/a` redirect is resolved. Human-readable URL shown by Bing. `title`, `url` — sitelinks under the main result. Ads served for this query, when present. Bing's related query suggestions. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/bing/search?query=coffee+machine&market=en-GB" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/bing/search?" + new URLSearchParams({ query: "coffee machine", market: "en-GB" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/bing/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "coffee machine", "market": "en-GB"}, ) data = res.json() ``` ```json Response theme={null} { "query": "coffee machine", "market": "en-GB", "total_results": 59300, "total_results_text": "About 59,300 results", "result_count": 8, "results": [ { "position": 1, "title": "The 9 Best Coffee Makers of 2026, Tested & Reviewed", "url": "https://www.seriouseats.com/best-coffee-makers-5069325", "display_url": "https://www.seriouseats.com/best-coffee-makers", "site_name": "Serious Eats", "snippet": "We brewed hundreds of cups to find the best drip coffee makers...", "deep_links": [ { "title": "Our Top Picks", "url": "https://www.seriouseats.com/best-coffee-makers-5069325#toc-our-top-picks" } ] } ], "ads": [ { "position": 1, "title": "Coffee Machines - Free Delivery", "url": "https://www.example-retailer.com/coffee", "display_url": "www.example-retailer.com", "snippet": "Shop our range of bean-to-cup machines." } ], "related_searches": ["best coffee machine 2026", "espresso machine", "bean to cup coffee machine"] } ``` ## Result depth Bing serves non-JS clients a server-rendered layout carrying the first **\~4–10 organic results**; the rest are lazy-loaded only in a real JS browser. The API returns everything Bing renders plus the true `total_results` — treat `count` as an upper bound and `result_count` as the truth. # Video Search Source: https://docs.scrapebadger.com/api-reference/endpoint/bing/videos GET https://scrapebadger.com/v1/bing/videos Search Bing Videos — title, thumbnail, duration, publisher, views and source platform per result. Search Bing Videos. Each result carries the destination video URL, thumbnail, duration, the host platform (e.g. YouTube), the publisher/channel, and views and age as displayed. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `espresso tutorial`. Bing market code, e.g. `en-US`. See [`/markets`](/api-reference/endpoint/bing/list-markets). Results to return. One of `off`, `moderate`, `strict`. ## Response Echo of the requested query. The market the results were fetched for. Videos returned. Video results. 1-based rank. Destination video URL. e.g. `00:54`. Host platform, e.g. `YouTube`. Channel / uploader. View count as displayed, e.g. `4.9K`. Age as displayed, e.g. `1 month ago`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/bing/videos?query=espresso+tutorial&count=10" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/bing/videos?" + new URLSearchParams({ query: "espresso tutorial", count: "10" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/bing/videos", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "espresso tutorial", "count": 10}, ) data = res.json() ``` ```json Response theme={null} { "query": "espresso tutorial", "market": "en-US", "result_count": 10, "results": [ { "position": 1, "title": "How to Make Espresso — Beginner's Guide", "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "thumbnail_url": "https://tse2.mm.bing.net/th?id=OVP.abc123", "duration": "08:12", "source": "YouTube", "publisher": "James Hoffmann", "views": "4.9M", "published": "1 year ago" } ] } ``` `views` and `published` are returned **as Bing displays them** (`4.9K`, `1 month ago`) — they are display strings, not numbers or timestamps. # Get Property Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/booking/get-property GET https://scrapebadger.com/v1/booking/properties/{country_code}/{slug} Full Booking.com property detail — description, address, GPS, score breakdown, facilities, room types, house rules, photos and guest Q&A. Fetch a single property's complete detail. The two path parameters are the two segments of a Booking hotel URL: ``` https://www.booking.com/hotel/it/radisson-collection-roma-antica.html ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ country_code slug ``` Both also come back on every [`/search`](/api-reference/endpoint/booking/search) result as `country_code` and `slug`. ## Path Parameters ISO country code from the property URL, e.g. `it`. Property slug from the property URL, e.g. `radisson-collection-roma-antica`. ## Query Parameters Photos to return. Maximum `100`. Guest Q\&A pairs to return. Maximum `50`. Locale for text, e.g. `fr`, `de`. ## Response Booking property id. Property name. Echo of the requested slug. Canonical property URL on booking.com. e.g. `Hotel`, `Apartment`. Booking accommodation type id. Stars, e.g. `5`. How the rating is denoted, e.g. `stars`. Full property description. Short summary line. Booking's "the fine print" notice, or `null`. Street address. Full single-line address. Neighbourhood, or `null`. Booking's internal city identifier. Overall score out of 10. Number of reviews. Sub-scores keyed by category. Property's own currency. Languages spoken at reception. Meal plans offered, e.g. `Breakfast`. e.g. `15:00`. Minimum age to check in, or `null`. Age restriction note, or `null`. Maximum guests in one booking, or `null`. Smoking permitted. Quiet hours enforced. Parties or events allowed. Curfew note, or `null`. Local regulation notice, or `null`. e.g. `free`, `charges_may_apply`. Number of facilities returned. Every facility Booking lists — typically 60–110 per hotel. e.g. `Free WiFi`. Booking facility id — usable as a `hotelfacility=` search filter. Facility group id. e.g. `free-wifi`. Facility is off the property. e.g. `free`, `paid`. Property highlights, e.g. `Top location: Highly rated by recent guests`. Room types offered. Room id — matches `blocks[].room_id` on [`/search`](/api-reference/endpoint/booking/search). e.g. `Deluxe Double Room`. Room size in square metres, or `null`. e.g. `King bed`. Room photo URLs. Property photo URLs, up to `photos`. Guest Q\&A pairs, up to `questions`. Property's answer, or `null`. ISO 8601 timestamp. ISO 8601 timestamp, or `null`. A property that does not exist returns `404`. ## Example ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/booking/properties/it/radisson-collection-roma-antica?photos=60&questions=20", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const property = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/booking/properties/it/radisson-collection-roma-antica", headers={"X-API-Key": "YOUR_API_KEY"}, params={"photos": 60, "questions": 20}, ) property = res.json() ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/booking/properties/it/radisson-collection-roma-antica?photos=60&questions=20" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} { "property_id": "1284937", "name": "Radisson Collection Hotel, Roma Antica", "slug": "radisson-collection-roma-antica", "url": "https://www.booking.com/hotel/it/radisson-collection-roma-antica.html", "accommodation_type": "Hotel", "accommodation_type_id": 204, "star_rating": 5, "star_rating_symbol": "stars", "description": "Set 400 metres from the Colosseum in the Centro Storico district, Radisson Collection Hotel, Roma Antica offers a rooftop restaurant, a fitness centre and air-conditioned rooms with free WiFi. Termini Station is a 15-minute walk away.", "summary": "5-star hotel in Centro Storico, 1.2 km from the centre", "fine_print": "Guests are required to show a photo ID and credit card at check-in. The city tax of EUR 7 per person per night is not included in the room rate.", "address": "Via Labicana 144", "formatted_address": "Via Labicana 144, Centro Storico, 00184 Rome, Italy", "city": "Rome", "district": "Centro Storico", "country": "Italy", "country_code": "it", "latitude": 41.8902, "longitude": 12.4964, "ufi": -126693, "is_city_centre": true, "is_old_town": true, "review_score": 8.9, "review_count": 1499, "score_breakdown": { "hotel_staff": 9.2, "hotel_clean": 9.1, "hotel_comfort": 9.0, "hotel_value": 8.1, "hotel_location": 9.4, "hotel_free_wifi": 9.3 }, "currency": "EUR", "languages_spoken": ["Italian", "English", "Spanish", "French"], "meal_plans": ["Breakfast", "Half board"], "house_rules": { "checkin_from": "15:00", "checkin_until": "00:00", "checkout_from": "07:00", "checkout_until": "11:00", "min_checkin_age": 18, "age_restriction": null, "group_limit": 8, "smoking": false, "quiet_hours": true, "quiet_hours_from": "23:00", "quiet_hours_until": "07:00", "parties": false, "curfew": null, "city_regulations": "A city tax of EUR 7 per person per night applies.", "pets_allowed": true, "pets_charge_mode": "charges_may_apply", "children_allowed": true, "min_children_age": 0, "cribs_allowed": true, "extra_beds_allowed": true }, "facilities_count": 87, "facilities": [ { "name": "Free WiFi", "facility_id": 107, "group_id": 15, "slug": "free-wifi", "is_offsite": false, "charge_mode": "free" }, { "name": "Fitness centre", "facility_id": 11, "group_id": 5, "slug": "fitness-centre", "is_offsite": false, "charge_mode": "free" }, { "name": "Airport shuttle", "facility_id": 17, "group_id": 3, "slug": "airport-shuttle", "is_offsite": true, "charge_mode": "paid" } ], "highlights": [ "Top location: Highly rated by recent guests (9.4)", "Breakfast info: Continental, Italian, Buffet", "Free private parking available on site" ], "rooms": [ { "room_id": "128493701", "room_type_id": 8, "name": "Deluxe Double Room with Colosseum View", "description": "This air-conditioned double room features a seating area, a minibar and a private bathroom with a rain shower. The room looks onto the Colosseum.", "size_m2": 32, "bathrooms": 1, "is_smoking": false, "max_persons": 2, "max_guests": 2, "max_children": 1, "beds": [{ "count": 1, "bed_type": "King bed" }], "photos": [ "https://cf.bstatic.com/xdata/images/hotel/max1024x768/1284937-deluxe-double.jpg" ] }, { "room_id": "128493705", "room_type_id": 9, "name": "Junior Suite", "description": "A suite with a separate living area, a terrace and a private bathroom with a bathtub.", "size_m2": 48, "bathrooms": 1, "is_smoking": false, "max_persons": 3, "max_guests": 3, "max_children": 2, "beds": [ { "count": 1, "bed_type": "King bed" }, { "count": 1, "bed_type": "Sofa bed" } ], "photos": [ "https://cf.bstatic.com/xdata/images/hotel/max1024x768/1284937-junior-suite.jpg" ] } ], "photos": [ "https://cf.bstatic.com/xdata/images/hotel/max1024x768/1284937-rooftop.jpg", "https://cf.bstatic.com/xdata/images/hotel/max1024x768/1284937-lobby.jpg", "https://cf.bstatic.com/xdata/images/hotel/max1024x768/1284937-facade.jpg" ], "questions": [ { "question_id": "9182736", "question": "Is the rooftop restaurant open to guests staying on a room-only rate?", "answer": "Yes, the rooftop restaurant is open to all in-house guests from 18:00 to 23:00.", "asked_at": "2026-06-04T11:22:00Z", "answered_at": "2026-06-05T08:14:00Z" }, { "question_id": "9182811", "question": "Do you have connecting rooms for a family of four?", "answer": null, "asked_at": "2026-08-01T16:40:00Z", "answered_at": null } ], "is_newly_opened": false, "is_sustainable": true, "sustainability_certifications": ["Green Key"] } ``` Each property-detail request costs **5 credits**. Failed requests are not charged. # Get Reviews Source: https://docs.scrapebadger.com/api-reference/endpoint/booking/get-reviews GET https://scrapebadger.com/v1/booking/properties/{country_code}/{slug}/reviews Paginated Booking.com guest reviews — positive and negative text, per-review score, stay dates, guest type, room stayed in, partner reply and photos. Page through a property's guest reviews. Booking splits each review into a `positive` and a `negative` half, either of which can be empty. Filter by review language or guest type, sort five ways, and paginate with `limit` and `offset` against `total_count`. ## Path Parameters ISO country code from the property URL, e.g. `it`. Property slug from the property URL, e.g. `radisson-collection-roma-antica`. ## Query Parameters Reviews per page. Maximum `100`. Number of reviews to skip. Sort order. One of `MOST_RELEVANT`, `NEWEST_FIRST`, `OLDEST_FIRST`, `SCORE_DESC`, `SCORE_ASC`. Only reviews written in this language, as an ISO code, e.g. `fr`. Only reviews from this guest type. One of `FAMILIES`, `COUPLES`, `GROUP_OF_FRIENDS`, `SOLO_TRAVELLERS`, `BUSINESS_TRAVELLERS`. Locale for category names and other text, e.g. `fr`, `de`. ## Response Booking property id. Total reviews matching the request — reflects `review_language` and `guest_type` when they are set. Sub-scores keyed by translated category name, e.g. `Staff`, `Facilities`, `Cleanliness`, `Comfort`, `Value for money`, `Location`, `Free Wifi`. Map of language code to review count, e.g. `{"en": 812, "fr": 111}`. Map of guest type to review count, e.g. `{"FAMILIES": 382}`. Echo of the requested page size. Echo of the requested offset. Echo of the requested sort order. Reviews for this page. Booking review id. Review headline. What the guest liked, or `null`. What the guest disliked, or `null`. Guest score out of 10. Publication timestamp (ISO 8601, UTC). Same timestamp as Unix seconds. Month of stay, e.g. `2026-07`. `YYYY-MM-DD`, or `null`. `YYYY-MM-DD`, or `null`. Nights stayed. ISO country code, e.g. `ie`. Avatar URL, or `null`. e.g. `COUPLES`. Room the guest stayed in — matches `rooms[].room_id` on [`/properties`](/api-reference/endpoint/booking/get-property). Language the review was written in. Permalink to the review on booking.com. Guests who marked the review helpful. Photo URLs attached to the review. The property's public reply, or `null`. `language_counts` and `guest_type_counts` let you size a filtered subset before you page it. A Rome hotel with **1,499** total reviews returns **111** with `review_language=fr` and **382** with `guest_type=FAMILIES` — read the counts once, then decide how many pages the filtered set actually needs. ## Example ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/booking/properties/it/radisson-collection-roma-antica/reviews?" + new URLSearchParams({ limit: "100", offset: "0", sort: "NEWEST_FIRST", guest_type: "FAMILIES", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); console.log(data.total_count, "family reviews"); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/booking/properties/it/radisson-collection-roma-antica/reviews", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "limit": 100, "offset": 0, "sort": "NEWEST_FIRST", "guest_type": "FAMILIES", }, ) data = res.json() print(data["total_count"], "family reviews") ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/booking/properties/it/radisson-collection-roma-antica/reviews?limit=100&offset=0&sort=NEWEST_FIRST&guest_type=FAMILIES" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} { "property_id": "1284937", "total_count": 382, "score_breakdown": { "Staff": 9.2, "Facilities": 8.8, "Cleanliness": 9.1, "Comfort": 9.0, "Value for money": 8.1, "Location": 9.4, "Free Wifi": 9.3 }, "language_counts": { "en": 812, "it": 246, "fr": 111, "de": 98, "es": 74 }, "guest_type_counts": { "FAMILIES": 382, "COUPLES": 611, "GROUP_OF_FRIENDS": 152, "SOLO_TRAVELLERS": 204, "BUSINESS_TRAVELLERS": 150 }, "limit": 100, "offset": 0, "sort": "NEWEST_FIRST", "reviews": [ { "review_id": "1284739201", "title": "Perfect base for a family week in Rome", "positive": "Ten minutes on foot to the Colosseum and the staff held our bags for four hours after checkout without being asked twice. The junior suite fitted all four of us comfortably.", "negative": "Breakfast gets very busy between 8 and 9 — go early or wait.", "score": 9.2, "date": "2026-08-12T09:41:22Z", "date_utc": 1786520482, "stay_date": "2026-07", "checkin_date": "2026-07-28", "checkout_date": "2026-08-02", "length_of_stay": 5, "guest_name": "Daniel", "guest_country": "Ireland", "guest_country_code": "ie", "guest_avatar": "https://q-xx.bstatic.com/xdata/images/avatar/1284739201.jpg", "guest_type": "FAMILIES", "room_id": "128493705", "room_name": "Junior Suite", "language": "en", "review_url": "https://www.booking.com/reviews/it/hotel/radisson-collection-roma-antica.html#1284739201", "is_approved": true, "is_anonymous": false, "helpful_votes": 14, "photos": [ "https://q-xx.bstatic.com/xdata/images/xphoto/1284739201-terrace.jpg" ], "partner_reply": "Thank you Daniel — we are glad the junior suite worked well for the family, and we have passed your breakfast note to the restaurant team." }, { "review_id": "1281002934", "title": "Emplacement idéal", "positive": "Chambre spacieuse et très propre, vue sur le Colisée depuis la fenêtre.", "negative": null, "score": 8.8, "date": "2026-07-30T18:02:10Z", "date_utc": 1785434530, "stay_date": "2026-07", "checkin_date": "2026-07-21", "checkout_date": "2026-07-24", "length_of_stay": 3, "guest_name": "Camille", "guest_country": "France", "guest_country_code": "fr", "guest_avatar": null, "guest_type": "FAMILIES", "room_id": "128493701", "room_name": "Deluxe Double Room with Colosseum View", "language": "fr", "review_url": "https://www.booking.com/reviews/it/hotel/radisson-collection-roma-antica.html#1281002934", "is_approved": true, "is_anonymous": false, "helpful_votes": 3, "photos": [], "partner_reply": null } ] } ``` Each reviews request costs **10 credits**. Failed requests are not charged. # Get Rooms & Rates Source: https://docs.scrapebadger.com/api-reference/endpoint/booking/get-rooms GET https://scrapebadger.com/v1/booking/properties/{country_code}/{slug}/rooms The full Booking.com rate table for one property and one set of dates — every room type with its per-room facilities, bed layouts and every bookable rate, plus meal plans and the child and bed policy. Fetch the **entire** rate table for a property on given dates. [`/search`](/api-reference/endpoint/booking/search) returns only the single cheapest rate per property; this endpoint returns every rate on every room type in one call — 30 rates across 5 priced room types for a Rome five-star, 68 rates across 11 room types for a Barcelona hotel. The two path parameters are the two segments of a Booking hotel URL: ``` https://www.booking.com/hotel/it/radisson-collection-roma-antica.html ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ country_code slug ``` Both also come back on every [`/search`](/api-reference/endpoint/booking/search) result as `country_code` and `slug`. ## Path Parameters ISO country code from the property URL, e.g. `it`. Property slug from the property URL, e.g. `radisson-collection-roma-antica`. ## Query Parameters Check-in date, `YYYY-MM-DD`. Check-out date, `YYYY-MM-DD`. Number of adults, `1`–`30`. Comma-separated children's ages, e.g. `4,9`. Number of rooms, `1`–`30`. Currency for prices, e.g. `EUR`, `GBP`. Locale for text and price formatting, e.g. `fr`, `de`. Also decides whether room sizes come back in square metres or square feet — see `area_unit`. ## Response Booking property id. Property name. Echo of the requested slug. Canonical property URL on booking.com. Echo of the check-in date. Echo of the check-out date. Echo of the requested adults. Echo of the requested children's ages, or `null`. Echo of the requested number of rooms. Currency the prices are quoted in. No availability for these dates. The room catalogue is still returned — see the note below. Unit for `rooms[].size_m2` — `SQUARE_METER` or `SQUARE_FEET`. Locale-driven: it follows the requested `language`. Total rates across every room. Every room type at the property. Room id — matches `rooms[].room_id` on [`/properties`](/api-reference/endpoint/booking/get-property) and `blocks[].room_id` on [`/search`](/api-reference/endpoint/booking/search). e.g. `Deluxe Double Room`. Room size in `area_unit`, or `null`. Floors this room type is on. Larger than the property's typical room. Cribs supplied free in this room. e.g. `ENTIRE_UNIT`. **Alternative** bed layouts for the same room — 2 single beds *or* 1 large double, not one flat list. Id of this layout. e.g. `Large double bed`. Facilities **of this room**, grouped by category — a single five-star room returned 33 across the three categories. [`/properties`](/api-reference/endpoint/booking/get-property) only carries property-level facilities. One of `BATHROOM_PRIVATE`, `VIEW`, `OTHER`. Facility names, e.g. `Rain shower`. Room highlights, e.g. `Colosseum view`. Room photo URLs. Every bookable rate for this room. Empty when the room has no availability for the dates. Booking's rate identifier, `____0` — already split into the four fields below. Room this rate belongs to. Guests the rate is priced for. Index into `meal_plans[]`. Total price for the requested stay. Booking's localized string, e.g. `€ 1.170`. Numeric value, e.g. `1170.4`. e.g. `EUR`. Rounded numeric value, e.g. `1170`. Struck-through price when discounted, same shape as `price`, else `null`. Per-night price, same shape as `price`. Taxes and charges line, e.g. `+€36 taxes and charges`. Booking's note on the rate, e.g. `Only 2 rooms left at this price`, or `null`. e.g. `Genius discount`. What the discount applies to. Numeric discount value. e.g. `EUR`. Rate badges, e.g. `9% off`. Meal plans referenced by `rates[].meal_plan_index`. e.g. `Breakfast included`. e.g. `BREAKFAST`. Price when not included, or `null`. Children and extra-bed rules, with priced age bands. Crib availability is guaranteed rather than on request. Lower bound of the age band. Upper bound of the age band. e.g. `CRIB`, `EXTRA_BED`. e.g. `FREE`, `FIXED`. e.g. `PER_NIGHT`, `PER_STAY`. Numeric charge, or `null` when free. Formatted charge, e.g. `€ 35`, or `null`. Every price is returned both as Booking's localized display string (`"€ 1.170"`) and as a numeric `amount` + `currency`. Always do arithmetic on `amount`, never on `display`. **Not every room is priced.** Rooms with no availability for the dates still come back with full detail — description, facilities, bed options, photos — but an empty `rates[]`. On one Rome five-star, 5 of 7 rooms were priced; on a Barcelona hotel, 11 of 16. **Sold out is a `200`, not an error.** When Booking has no availability at all for the dates you get `is_sold_out: true`, `rate_count: 0` and an empty `rates[]` on every room — the room catalogue, facilities and highlights are still returned. The same Rome guesthouse returns `is_sold_out: true` with 0 rates for `2026-09-10` and `is_sold_out: false` with 22 rates for `2026-12-05`. Branch on `is_sold_out`, not on a failed request. A property that does not exist returns `404`. Missing `checkin`/`checkout`, or a malformed `children` value, returns `400`. ## Example ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/booking/properties/it/radisson-collection-roma-antica/rooms?" + new URLSearchParams({ checkin: "2026-12-05", checkout: "2026-12-08", adults: "2", children: "4,9", currency: "EUR", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); console.log(data.rate_count, "rates across", data.rooms.length, "room types"); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/booking/properties/it/radisson-collection-roma-antica/rooms", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "checkin": "2026-12-05", "checkout": "2026-12-08", "adults": 2, "children": "4,9", "currency": "EUR", }, ) data = res.json() print(data["rate_count"], "rates across", len(data["rooms"]), "room types") ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/booking/properties/it/radisson-collection-roma-antica/rooms?checkin=2026-12-05&checkout=2026-12-08&adults=2&children=4%2C9¤cy=EUR" \ -H "X-API-Key: YOUR_API_KEY" ``` Trimmed to 2 of 7 rooms and 3 of 30 rates: ```json Response theme={null} { "property_id": "1284937", "name": "Radisson Collection Hotel, Roma Antica", "slug": "radisson-collection-roma-antica", "url": "https://www.booking.com/hotel/it/radisson-collection-roma-antica.html", "checkin": "2026-12-05", "checkout": "2026-12-08", "adults": 2, "children": "4,9", "rooms_requested": 1, "currency": "EUR", "is_sold_out": false, "area_unit": "SQUARE_METER", "rate_count": 30, "rooms": [ { "room_id": "128493701", "room_type_id": 8, "name": "Deluxe Double Room with Colosseum View", "description": "This air-conditioned double room features a seating area, a minibar and a private bathroom with a rain shower. The room looks onto the Colosseum.", "size_m2": 32, "floors": [3, 4, 5], "bathrooms": 1, "is_smoking": false, "is_bigger_than_average": true, "cribs_free": true, "max_persons": 3, "max_guests": 3, "max_children": 1, "privacy_level": "ENTIRE_UNIT", "bed_options": [ { "configuration_id": 1, "beds": [{ "count": 1, "bed_type": "Large double bed" }] }, { "configuration_id": 2, "beds": [{ "count": 2, "bed_type": "Single bed" }] } ], "facilities": [ { "category": "BATHROOM_PRIVATE", "facilities": ["Rain shower", "Bathrobe", "Free toiletries", "Hairdryer"] }, { "category": "VIEW", "facilities": ["Landmark view", "City view"] }, { "category": "OTHER", "facilities": ["Air conditioning", "Minibar", "Safety deposit box", "Free WiFi"] } ], "highlights": ["Colosseum view", "32 m²", "Air conditioning"], "photos": [ "https://cf.bstatic.com/xdata/images/hotel/max1024x768/1284937-deluxe-double.jpg" ], "rates": [ { "block_id": "128493701_412880094_2_0_0", "room_id": "128493701", "rate_id": 412880094, "occupancy": 2, "meal_plan_index": 0, "price": { "display": "€ 1.170", "amount": 1170.4, "currency": "EUR", "rounded": 1170 }, "price_before_discount": { "display": "€ 1.286", "amount": 1286.15, "currency": "EUR", "rounded": 1286 }, "price_per_night": { "display": "€ 390", "amount": 390.13, "currency": "EUR", "rounded": 390 }, "charges_info": "+€ 63 taxes and charges", "info_message": "Only 2 rooms left at this price", "discounts": [ { "name": "Genius discount", "description": "You are getting a reduced rate because you are a Genius member.", "item_type": "ROOM", "amount": 115.75, "currency": "EUR" } ], "badges": ["9% off"] }, { "block_id": "128493701_412880094_2_1_0", "room_id": "128493701", "rate_id": 412880094, "occupancy": 2, "meal_plan_index": 1, "price": { "display": "€ 1.320", "amount": 1320.4, "currency": "EUR", "rounded": 1320 }, "price_before_discount": null, "price_per_night": { "display": "€ 440", "amount": 440.13, "currency": "EUR", "rounded": 440 }, "charges_info": "+€ 63 taxes and charges", "info_message": null, "discounts": [], "badges": [] }, { "block_id": "128493701_412880102_3_0_0", "room_id": "128493701", "rate_id": 412880102, "occupancy": 3, "meal_plan_index": 0, "price": { "display": "€ 1.455", "amount": 1455.0, "currency": "EUR", "rounded": 1455 }, "price_before_discount": null, "price_per_night": { "display": "€ 485", "amount": 485.0, "currency": "EUR", "rounded": 485 }, "charges_info": "+€ 63 taxes and charges", "info_message": null, "discounts": [], "badges": [] } ] }, { "room_id": "128493709", "room_type_id": 12, "name": "Classic Single Room", "description": "A compact air-conditioned single room with a private bathroom and a courtyard outlook.", "size_m2": 18, "floors": [1, 2], "bathrooms": 1, "is_smoking": false, "is_bigger_than_average": false, "cribs_free": false, "max_persons": 1, "max_guests": 1, "max_children": 0, "privacy_level": "ENTIRE_UNIT", "bed_options": [ { "configuration_id": 1, "beds": [{ "count": 1, "bed_type": "Single bed" }] } ], "facilities": [ { "category": "BATHROOM_PRIVATE", "facilities": ["Shower", "Free toiletries", "Hairdryer"] }, { "category": "OTHER", "facilities": ["Air conditioning", "Free WiFi", "Desk"] } ], "highlights": ["18 m²", "Air conditioning"], "photos": [ "https://cf.bstatic.com/xdata/images/hotel/max1024x768/1284937-classic-single.jpg" ], "rates": [] } ], "meal_plans": [ { "meal_plan_id": 1, "name": "Breakfast included", "meal_type": "BREAKFAST", "breakfast_included": true, "breakfast_price": null, "lunch_included": false, "lunch_price": null, "dinner_included": false, "dinner_price": null }, { "meal_plan_id": 3, "name": "Half board", "meal_type": "HALF_BOARD", "breakfast_included": true, "breakfast_price": null, "lunch_included": false, "lunch_price": null, "dinner_included": true, "dinner_price": null } ], "child_and_bed_policy": { "children_allowed": true, "min_children_age": 0, "cribs_allowed": true, "extra_beds_allowed": true, "cribs_guaranteed": false, "rules": [ { "rule_id": 1, "age_from": 0, "age_to": 2, "rule_type": "CRIB", "price_type": "FREE", "price_mode": "PER_NIGHT", "price": null, "localized_price": null }, { "rule_id": 2, "age_from": 3, "age_to": 17, "rule_type": "EXTRA_BED", "price_type": "FIXED", "price_mode": "PER_NIGHT", "price": 35.0, "localized_price": "€ 35" } ] } } ``` The usual flow: [`/search`](/api-reference/endpoint/booking/search) for the shortlist, take `country_code` + `slug` off any result, then call `/rooms` for that property's full rate table. Each rooms request costs **10 credits**. Failed requests are not charged. # Search Properties Source: https://docs.scrapebadger.com/api-reference/endpoint/booking/search GET https://scrapebadger.com/v1/booking/search Search Booking.com stays by destination — with dates, occupancy, sorting and Booking's own filter ids, returning numeric prices alongside display strings. Search Booking.com for stays. Target an area either with free-text `location` (geocoded by Booking) **or** with an exact `dest_id` + `dest_type` pair from [`/destinations`](/api-reference/endpoint/booking/search-destinations). Page through results with `offset` against `total_results`. ## Query Parameters Free-text destination, geocoded by Booking — e.g. `Rome, Italy`, `Amsterdam`, `Trastevere`. Provide either `location` **or** `dest_id` + `dest_type`. Exact Booking destination id from [`/destinations`](/api-reference/endpoint/booking/search-destinations). Requires `dest_type`. Destination type that goes with `dest_id` — `CITY`, `DISTRICT`, `AIRPORT`, `LANDMARK` or `REGION`. Check-in date, `YYYY-MM-DD`. Pass both `checkin` and `checkout`, or neither. Check-out date, `YYYY-MM-DD`. Number of adults, `1`–`30`. Comma-separated children's ages, e.g. `4,9`. Number of rooms. Number of properties to skip. Properties per page. Maximum `100`. Sort order. One of `popularity`, `price`, `class_descending`, `class_ascending`, `distance_from_search`, `bayesian_review_score`, `review_score_and_price`, `upsort_bh`. An unrecognised value is rejected with a `400`. Semicolon-separated Booking filter ids, e.g. `class=5;mealplan=1`. See [Filters](#filters) below. Currency for prices, e.g. `EUR`, `GBP`. Locale for text and price formatting, e.g. `fr`, `de`. ## Filters `filters` takes Booking's own filter ids, joined with `;`. These are the verified ones, with their effect on a Rome search that returns **5,982** properties unfiltered: | `filters` value | Meaning | Results | | - | - | - | | `class=5` | 5-star properties | 67 | | `class=5;hotelfacility=107` | 5-star with a specific facility | 64 | | `price=EUR-50-100-1` | €50–100 per night | 410 | | `review_score=80` | Review score 8.0+ | 4,552 | | `ht_id=204` | Apartments | 705 | | `mealplan=1` | Breakfast included | 1,074 | | `fc=2` | Free cancellation | 5,370 | | `distance=1000` | Within 1 km of the centre | 629 | An unknown filter id is ignored by Booking rather than rejected — the search succeeds and simply returns the unfiltered count. Check `total_results` to confirm a filter actually applied. ## Response Echo of the requested destination. The destination Booking resolved the search to. Booking destination id. e.g. `CITY`. e.g. `Rome`. e.g. `Rome, Lazio, Italy`. ISO country code, e.g. `it`. Echo of the check-in date, or `null`. Echo of the check-out date, or `null`. Currency the prices are quoted in. Total matching properties across all pages, after `filters`. Echo of the requested offset. Properties returned on this page. Property cards for this page. Booking property id. Property name. URL slug — feed to [`/properties/{country_code}/{slug}`](/api-reference/endpoint/booking/get-property). Canonical property URL on booking.com. Booking accommodation type id, e.g. `204` for apartments. Short property blurb. ISO country code — the first path segment for the detail endpoints. Booking's internal city identifier. Location line as shown on the card, e.g. `Centro Storico, Rome`. Formatted distance, e.g. `0.6 km from centre`. Same distance in metres. Distance to the nearest public transport, or `null`. Distance to the nearest beach, or `null`. Review score out of 10. Number of reviews. Localized score word, e.g. `Fabulous`. Stars, e.g. `5`. Why the property is unavailable, when it is. Booking badges, e.g. `["Genius"]`. How many travellers saved the property. Meal plan on the quoted rate, e.g. `Breakfast included`. Taxes and charges line, e.g. `+€36 taxes and charges`. Total price for the requested stay. Booking's localized string, e.g. `€ 265,09`. Numeric value, e.g. `265.09`. e.g. `EUR`. Rounded numeric value, e.g. `265`. Struck-through price when discounted, same shape as `price`, else `null`. Per-night price, same shape as `price`. The room the quoted price is for. e.g. `Deluxe Double Room`. e.g. `["Bedroom", "Bathroom"]`. Bed configuration lines, e.g. `["1 king bed"]`. Room size. e.g. `m2`. The bookable rate blocks on the card. Room id — matches `rooms[].room_id` on [`/properties`](/api-reference/endpoint/booking/get-property). Guests the block sleeps. e.g. `Breakfast included`. Same shape as `price`. Pre-discount price, or `null`. ISO 8601 deadline, or `null`. Full-size photo URL. Thumbnail photo URL. Every price is returned both as Booking's localized display string (`"€ 265,09"`) and as a numeric `amount` + `currency`. The display string is locale-formatted — comma decimal separators, currency symbol placement — so always do arithmetic on `amount`, never on `display`. ## Example ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/booking/search?" + new URLSearchParams({ location: "Rome, Italy", checkin: "2026-09-12", checkout: "2026-09-15", adults: "2", children: "4,9", sort: "bayesian_review_score", filters: "class=5;mealplan=1", currency: "EUR", limit: "25", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/booking/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "location": "Rome, Italy", "checkin": "2026-09-12", "checkout": "2026-09-15", "adults": 2, "children": "4,9", "sort": "bayesian_review_score", "filters": "class=5;mealplan=1", "currency": "EUR", "limit": 25, }, ) data = res.json() ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/booking/search?location=Rome%2C%20Italy&checkin=2026-09-12&checkout=2026-09-15&adults=2&children=4%2C9&sort=bayesian_review_score&filters=class%3D5%3Bmealplan%3D1¤cy=EUR&limit=25" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} { "query": "Rome, Italy", "destination": { "dest_id": "-126693", "dest_type": "CITY", "name": "Rome", "label": "Rome, Lazio, Italy", "country_code": "it" }, "checkin": "2026-09-12", "checkout": "2026-09-15", "currency": "EUR", "total_results": 1074, "offset": 0, "count": 25, "properties": [ { "property_id": "1284937", "name": "Radisson Collection Hotel, Roma Antica", "slug": "radisson-collection-roma-antica", "url": "https://www.booking.com/hotel/it/radisson-collection-roma-antica.html", "accommodation_type_id": 204, "description": "Set 400 metres from the Colosseum, this 5-star hotel offers a rooftop restaurant and air-conditioned rooms with free WiFi.", "address": "Via Labicana 144", "city": "Rome", "country_code": "it", "latitude": 41.8902, "longitude": 12.4964, "ufi": -126693, "display_location": "Centro Storico, Rome", "distance_to_centre": "1.2 km from centre", "distance_to_centre_metres": 1204, "is_centrally_located": true, "public_transport_distance": "300 m from Colosseo metro", "beach_distance": null, "review_score": 8.9, "review_count": 1499, "review_score_word": "Fabulous", "star_rating": 5, "is_preferred": true, "is_preferred_plus": false, "is_genius_rate_available": true, "is_newly_opened": false, "is_closed": false, "is_sold_out": false, "sold_out_messages": [], "is_sustainable": true, "sustainability_certifications": ["Green Key"], "badges": ["Genius"], "wishlist_count": 3812, "free_cancellation": true, "no_prepayment": true, "pets_allowed_free": false, "meal_plan": "Breakfast included", "charges_info": "+€36 taxes and charges", "price": { "display": "€ 795,27", "amount": 795.27, "currency": "EUR", "rounded": 795 }, "price_before_discount": { "display": "€ 946,75", "amount": 946.75, "currency": "EUR", "rounded": 947 }, "price_per_night": { "display": "€ 265,09", "amount": 265.09, "currency": "EUR", "rounded": 265 }, "room": { "name": "Deluxe Double Room with Colosseum View", "unit_types": ["Bedroom", "Bathroom"], "beds": ["1 king bed"], "total_beds": 1, "bedrooms": 1, "bathrooms": 1, "kitchens": 0, "living_rooms": 0, "area": 32, "area_unit": "m2" }, "blocks": [ { "room_id": "128493701", "occupancy": 2, "meal_plan_id": 1, "meal_plan": "Breakfast included", "price": { "display": "€ 795,27", "amount": 795.27, "currency": "EUR", "rounded": 795 }, "original_price": { "display": "€ 946,75", "amount": 946.75, "currency": "EUR", "rounded": 947 }, "free_cancellation_until": "2026-09-10T23:59:00Z" } ], "photo": "https://cf.bstatic.com/xdata/images/hotel/max1024x768/1284937-rooftop.jpg", "thumbnail": "https://cf.bstatic.com/xdata/images/hotel/square200/1284937-rooftop.jpg" } ] } ``` Each search request costs **5 credits**. Failed requests are not charged. **Two pagination traps.** `total_results` is Booking's own *estimate* — the same query returns a slightly different number between calls (we measured 5,974-5,977 for one Rome search), so never use it as a loop bound or a completeness check. And an `offset` past the real end returns a **full page of tail results**, not an empty page — so a naive "loop until empty" never terminates. Page by deduplicating on `property_id` and stop when a page adds nothing new. For sizing a crawl up front, use `property_count` from [`/destinations`](/api-reference/endpoint/booking/search-destinations), which is an exact inventory count. # Search Destinations Source: https://docs.scrapebadger.com/api-reference/endpoint/booking/search-destinations GET https://scrapebadger.com/v1/booking/destinations Resolve free text to Booking.com destination ids — cities, districts, airports, landmarks and regions, with GPS and country. Turn free text into exact Booking destinations. Works on prefixes, so `amsterd` already resolves. Each result carries a `dest_id` and `dest_type` pair you can pass to [`/search`](/api-reference/endpoint/booking/search) to target an exact area instead of relying on free-text geocoding. ## Query Parameters Free-text destination, including prefixes — e.g. `amsterd`, `Rome`, `Charles de Gaulle`. Destinations to return. Maximum `20`. Locale for names and labels, e.g. `fr`, `de`. ## Response Echo of the requested text. Destinations returned. Matching destinations, best match first. Booking destination id — pass to [`/search`](/api-reference/endpoint/booking/search) with `dest_type`. One of `CITY`, `DISTRICT`, `AIRPORT`, `LANDMARK`, `REGION`. Destination name, e.g. `Amsterdam`. Full label, e.g. `Amsterdam, Noord-Holland, Netherlands`. Parent city, or `null`. Region or province, or `null`. Country name. ISO country code, e.g. `nl`. Total bookable properties in this destination — `hotel_count` + `home_count`. This is Booking's own inventory count and is the right number to size a crawl against; `total_results` on `/search` is an estimate and moves between identical calls. Hotels, hostels, guesthouses and similar in this destination. Apartments, villas and other entire-home listings in this destination. Destination photo URL, or `null`. The two-step workflow: resolve here once, cache the `dest_id` + `dest_type`, then pass both to [`/search`](/api-reference/endpoint/booking/search) on every subsequent query. That pins the search to exactly the city, district or airport you meant — free-text `location` re-geocodes each time and can drift to a same-named place in another country. ## Example ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/booking/destinations?" + new URLSearchParams({ query: "amsterd", limit: "5" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { destinations } = await res.json(); const city = destinations.find((d) => d.dest_type === "CITY"); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/booking/destinations", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "amsterd", "limit": 5}, ) destinations = res.json()["destinations"] city = next(d for d in destinations if d["dest_type"] == "CITY") ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/booking/destinations?query=amsterd&limit=5" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} { "query": "amsterd", "count": 3, "destinations": [ { "dest_id": "-2140479", "dest_type": "CITY", "name": "Amsterdam", "label": "Amsterdam, Noord-Holland, Netherlands", "city": "Amsterdam", "region": "Noord-Holland", "country": "Netherlands", "country_code": "nl", "latitude": 52.3731, "longitude": 4.8922, "image_url": "https://cf.bstatic.com/xdata/images/city/600x600/688884-amsterdam.jpg" }, { "dest_id": "-2140558", "dest_type": "AIRPORT", "name": "Amsterdam Schiphol Airport", "label": "Amsterdam Schiphol Airport, Netherlands", "city": "Haarlemmermeer", "region": "Noord-Holland", "country": "Netherlands", "country_code": "nl", "latitude": 52.3105, "longitude": 4.7683, "image_url": null }, { "dest_id": "1926", "dest_type": "DISTRICT", "name": "Amsterdam City Centre", "label": "Amsterdam City Centre, Amsterdam, Netherlands", "city": "Amsterdam", "region": "Noord-Holland", "country": "Netherlands", "country_code": "nl", "latitude": 52.3728, "longitude": 4.8936, "image_url": null } ] } ``` Each destinations request costs **3 credits**. Failed requests are not charged. # Ask ChatGPT Source: https://docs.scrapebadger.com/api-reference/endpoint/chatgpt/ask GET https://scrapebadger.com/v1/chatgpt/ask Send a prompt to the real chatgpt.com and get the answer as structured JSON, with citations anchored to character offsets in the answer text. Ask **the real `chatgpt.com`** a question anonymously and get the answer back as JSON — plus every web source ChatGPT retrieved, which of those it cited, and exactly which span of the answer each citation supports. Accepts `GET` (query params) or `POST` (JSON body) with identical fields. **Credits:** 20 Typical latency is **20-25s ungrounded, 30-70s with web search** — this is a live answer, not a cache. Set your client timeout to at least 60 s. ## Authorization Your ScrapeBadger API key. ## Query Parameters The question to ask. Maximum **4,096 characters**. Each request is standalone — there is no conversation memory, so include all the context you need here. ISO-3166 alpha-2 egress country, e.g. `US`, `GB`, `DE`. Changes the localised results ChatGPT retrieves. Whether ChatGPT should browse the web. One of: * `auto` — let ChatGPT decide (default). * `force` — instruct it to search the web. * `off` — answer from the model's own knowledge only. Check `web_search_triggered` in the response for what actually happened. Public `http(s)` URL of an image to attach to the prompt. ChatGPT looks at the picture and answers about it. JPEG, PNG, GIF, WEBP and BMP; up to 5 MB. Supply the picture **either** as `image_url` **or** as `image_base64` — sending both is a `400`. The image itself, base64-encoded — **`POST` only**, since a whole image does not belong in a query string. A bare base64 payload and a `data:image/png;base64,...` URL are both accepted. An image ask is slower than a text one: ChatGPT uploads the picture before it starts answering. Allow **90-150 s**. This is image **input** only. Anonymous chatgpt.com will not GENERATE an image — its own logged-out page gates that behind a login — so no request to this endpoint can return a picture it drew. `images` in the response is what the answer *displayed*. ## Response Echo of the prompt you sent. The answer as plain text. Citation offsets index into this string. The answer with its original Markdown formatting, when available. The sources ChatGPT actually referenced in the answer. Source URL. Page title. Snippet ChatGPT retrieved from the page. Hostname, e.g. `techcrunch.com`. Publisher/attribution label as shown by ChatGPT. Publication date as a Unix timestamp. Publication date as an ISO-8601 UTC string. Character offset in `answer` where the supported span begins. Character offset in `answer` where the supported span ends. The substring of `answer` this source supports. The **full** set ChatGPT retrieved — including results it looked at but did not cite. Empty when `web_search_triggered` is `false`. Result URL. Result title. Retrieved snippet. Hostname. Publisher/attribution label. Publication date as a Unix timestamp. Publication date as an ISO-8601 UTC string. Index of this result in ChatGPT's own reference list. Whether this result made it into `citations`. Images the answer displayed — product shots, article art and other pictures a web-grounded answer pulls in. Favicon-sized assets are excluded. Never a generated image: see the warning above. Image URL. Alt text, when ChatGPT supplied one. Distinct hostnames across the cited sources — a quick view of who ChatGPT trusted. Whether ChatGPT **actually** browsed the web for this answer. ChatGPT's internal reference markers, e.g. `turn0search1`, `turn0news20`. Which model answered, e.g. `gpt-5-5`. Reported, not requestable. Identifier of the one-shot exchange. Not a handle you can continue from. Identifier of the answer message. Echo of the egress country used. Length of `answer` in characters. Number of entries in `citations`. End-to-end time to produce the answer, in milliseconds. Answer creation time as a Unix timestamp. Answer creation time as an ISO-8601 UTC string. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/chatgpt/ask?prompt=Which%20companies%20lead%20the%20web%20scraping%20API%20market%3F&country=US&web_search=force" \ -H "X-API-Key: YOUR_API_KEY" \ --max-time 60 ``` ```javascript Node.js theme={null} const res = await fetch("https://scrapebadger.com/v1/chatgpt/ask", { method: "POST", headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ prompt: "Which companies lead the web scraping API market?", country: "US", web_search: "force", }), signal: AbortSignal.timeout(60_000), }); const data = await res.json(); for (const c of data.citations) { console.log(`${c.domain} → "${c.matched_text}"`); } ``` ```python Python theme={null} import requests res = requests.post( "https://scrapebadger.com/v1/chatgpt/ask", headers={"X-API-Key": "YOUR_API_KEY"}, json={ "prompt": "Which companies lead the web scraping API market?", "country": "US", "web_search": "force", }, timeout=60, ) data = res.json() for c in data["citations"]: print(c["domain"], "→", data["answer"][c["start_index"]:c["end_index"]]) ``` ```json Response theme={null} { "prompt": "Which companies lead the web scraping API market?", "answer": "The web scraping API market in 2026 is led by a handful of infrastructure providers. Bright Data remains the largest by revenue, with a proxy network spanning residential and mobile exits. Oxylabs and Zyte compete directly on enterprise contracts, while newer entrants such as ScrapeBadger and ScrapingBee focus on per-endpoint APIs with predictable credit pricing.", "answer_markdown": "The web scraping API market in 2026 is led by a handful of infrastructure providers. **Bright Data** remains the largest by revenue, with a proxy network spanning residential and mobile exits. **Oxylabs** and **Zyte** compete directly on enterprise contracts, while newer entrants such as **ScrapeBadger** and **ScrapingBee** focus on per-endpoint APIs with predictable credit pricing.", "citations": [ { "url": "https://research.example.com/web-scraping-market-2026", "title": "Web Scraping Market Report 2026", "snippet": "Bright Data continues to hold the largest share of the commercial web data market...", "domain": "research.example.com", "attribution": "Example Research", "pub_date_utc": 1751328000.0, "published_at": "2026-07-01T00:00:00Z", "start_index": 103, "end_index": 213, "matched_text": "Bright Data remains the largest by revenue, with a proxy network spanning residential and mobile exits." }, { "url": "https://news.example.org/scraping-api-pricing-shakeup", "title": "The scraping API pricing shakeup", "snippet": "Credit-based per-endpoint pricing has become the default for newer vendors...", "domain": "news.example.org", "attribution": "Example News", "pub_date_utc": 1753747200.0, "published_at": "2026-07-29T00:00:00Z", "start_index": 214, "end_index": 366, "matched_text": "Oxylabs and Zyte compete directly on enterprise contracts, while newer entrants such as ScrapeBadger and ScrapingBee focus on per-endpoint APIs with predictable credit pricing." } ], "search_results": [ { "url": "https://research.example.com/web-scraping-market-2026", "title": "Web Scraping Market Report 2026", "snippet": "Bright Data continues to hold the largest share of the commercial web data market...", "domain": "research.example.com", "attribution": "Example Research", "pub_date_utc": 1751328000.0, "published_at": "2026-07-01T00:00:00Z", "ref_index": 0, "cited": true }, { "url": "https://news.example.org/scraping-api-pricing-shakeup", "title": "The scraping API pricing shakeup", "snippet": "Credit-based per-endpoint pricing has become the default for newer vendors...", "domain": "news.example.org", "attribution": "Example News", "pub_date_utc": 1753747200.0, "published_at": "2026-07-29T00:00:00Z", "ref_index": 1, "cited": true }, { "url": "https://forum.example.net/thread/best-scraping-api", "title": "Best scraping API in 2026? — discussion", "snippet": "Long thread comparing per-request costs across eight vendors...", "domain": "forum.example.net", "attribution": null, "pub_date_utc": null, "published_at": null, "ref_index": 2, "cited": false } ], "source_domains": ["research.example.com", "news.example.org"], "web_search_triggered": true, "search_queries": ["turn0search0", "turn0news1"], "model": "gpt-5-5", "conversation_id": "6a1f2c9e-3d54-4b17-9f0a-2c7de51b8a44", "message_id": "b03d7f18-5c2a-49e6-8f31-77d1c0a9e512", "country": "US", "answer_length": 366, "citation_count": 2, "latency_ms": 24817, "created_utc": 1754323200.0, "created_at": "2026-08-04T16:00:00Z" } ``` `search_results` is the full retrieved set; `citations` is the subset that made it into the answer. When `web_search_triggered` is `false`, both are empty and ChatGPT answered from its own knowledge — that is a valid response, not an error. ## Asking about an image Attach a picture and ChatGPT answers about it. `image_url` works on `GET` and `POST`; `image_base64` is `POST` only. ```bash cURL theme={null} curl -X POST "https://scrapebadger.com/v1/chatgpt/ask" \ -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "prompt": "What product is in this photo, and what is it usually used for?", "image_url": "https://example.com/product.jpg" }' \ --max-time 150 ``` ```python Python theme={null} import base64, requests with open("product.jpg", "rb") as fh: encoded = base64.b64encode(fh.read()).decode() res = requests.post( "https://scrapebadger.com/v1/chatgpt/ask", headers={"X-API-Key": "YOUR_API_KEY"}, json={ "prompt": "What product is in this photo, and what is it usually used for?", "image_base64": encoded, }, timeout=150, ) print(res.json()["answer"]) ``` ```javascript Node.js theme={null} import { readFile } from "node:fs/promises"; const encoded = (await readFile("product.jpg")).toString("base64"); const res = await fetch("https://scrapebadger.com/v1/chatgpt/ask", { method: "POST", headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ prompt: "What product is in this photo, and what is it usually used for?", image_base64: encoded, }), signal: AbortSignal.timeout(150_000), }); console.log((await res.json()).answer); ``` An image ChatGPT cannot read is a `400` with `"code": "invalid_image"`, raised before the request reaches a browser — so a broken picture never costs you credits. Sending both `image_url` and `image_base64` is also a `400`. ChatGPT is non-deterministic. The same prompt can return different wording and different sources on each call. For tracking, sample on a schedule and aggregate. # Brand Visibility Source: https://docs.scrapebadger.com/api-reference/endpoint/chatgpt/brand-visibility GET https://scrapebadger.com/v1/chatgpt/brand-visibility Ask ChatGPT a question and get a full AEO/GEO analysis of how your brand appears in the answer — mentions, position, share of voice against competitors, and whether your domain was cited. Ask **the real `chatgpt.com`** a buyer-intent question and get back both the answer **and** a structured analysis of how your brand fares in it: whether it was mentioned, how early, how often, how it compares to named competitors, and whether your domain was cited as a source. This is the **AEO / GEO** (Answer Engine / Generative Engine Optimisation) measurement that vendors like Profound, Otterly, Peec and AthenaHQ sell as a \$99–989/month subscription — here it is one 25-credit call. Accepts `GET` (query params) or `POST` (JSON body). **Credits:** 25 Typical latency is **20-25s ungrounded, 30-70s with web search**. Set your client timeout to at least 60 s. ## Authorization Your ScrapeBadger API key. ## Query Parameters The question to ask ChatGPT — typically a buyer-intent prompt like `best web scraping API for e-commerce`. Maximum 4,096 characters. The brand name to look for in the answer, e.g. `ScrapeBadger`. Your domain, e.g. `scrapebadger.com`. Used to decide `cited`, `cited_urls` and `citation_rank`. Alternate spellings that also count as a mention of `brand` — e.g. `Scrape Badger,scrape-badger`. **Comma-separated on `GET`; a `string[]` on `POST`.** Competitor names to measure against, e.g. `Bright Data,Oxylabs,Zyte`. Drives `share_of_voice_pct` and the `competitors` array. **Comma-separated on `GET`; a `string[]` on `POST`.** ISO-3166 alpha-2 egress country. Visibility often differs by market. One of `auto`, `force`, `off`. **Defaults to `force`** here — visibility tracking usually wants ChatGPT to actually browse. Check `web_search_triggered` for what happened. ## Response Echo of the prompt you sent. Echo of the brand you tracked. Echo of the domain you supplied. Whether the brand (or any alias) appears in the answer. How many times the brand or its aliases appear. Character offset of the first mention in `answer`. `null` when absent. How prominently the brand is placed: `1.0` = named at the very start of the answer, `0.0` = absent. Useful as a single trendable number. Brand mentions as a percentage of brand + competitor mentions. `0` when nobody is mentioned. Whether the brand's `domain` appears among the answer's cited sources. The cited URLs belonging to the brand's domain. 1-based rank of the brand's first cited URL within the citation list. `null` when not cited. One entry per competitor you named, in the order you supplied them. Competitor name as supplied. Whether it appears in the answer. How many times it appears. Character offset of its first mention. Whether a URL on its domain is cited. Its cited URLs. The answer text surrounding the first brand mention — ready to quote in a report. The full answer text. The sources ChatGPT referenced — same shape as [`/ask`](/api-reference/endpoint/chatgpt/ask). Source URL. Page title. Retrieved snippet. Hostname. Publisher/attribution label. Publication date as a Unix timestamp. Publication date as an ISO-8601 UTC string. Character offset in `answer` where the supported span begins. Character offset in `answer` where the supported span ends. The substring of `answer` this source supports. Whether ChatGPT actually browsed the web. Which model answered, e.g. `gpt-5-5`. Echo of the egress country used. End-to-end time in milliseconds. Answer creation time as a Unix timestamp. Answer creation time as an ISO-8601 UTC string. ## Example ```bash cURL theme={null} curl -G "https://scrapebadger.com/v1/chatgpt/brand-visibility" \ -H "X-API-Key: YOUR_API_KEY" \ --data-urlencode "prompt=What is the best web scraping API for e-commerce data?" \ --data-urlencode "brand=ScrapeBadger" \ --data-urlencode "domain=scrapebadger.com" \ --data-urlencode "aliases=Scrape Badger,scrape-badger" \ --data-urlencode "competitors=Bright Data,Oxylabs,Zyte" \ --data-urlencode "country=US" \ --max-time 60 ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/chatgpt/brand-visibility", { method: "POST", headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ prompt: "What is the best web scraping API for e-commerce data?", brand: "ScrapeBadger", domain: "scrapebadger.com", aliases: ["Scrape Badger", "scrape-badger"], competitors: ["Bright Data", "Oxylabs", "Zyte"], country: "US", }), signal: AbortSignal.timeout(60_000), }, ); const data = await res.json(); console.log( `mentioned=${data.mentioned} sov=${data.share_of_voice_pct}% cited=${data.cited}`, ); ``` ```python Python theme={null} import requests res = requests.post( "https://scrapebadger.com/v1/chatgpt/brand-visibility", headers={"X-API-Key": "YOUR_API_KEY"}, json={ "prompt": "What is the best web scraping API for e-commerce data?", "brand": "ScrapeBadger", "domain": "scrapebadger.com", "aliases": ["Scrape Badger", "scrape-badger"], "competitors": ["Bright Data", "Oxylabs", "Zyte"], "country": "US", }, timeout=60, ) data = res.json() print(data["mentioned"], data["share_of_voice_pct"], data["citation_rank"]) ``` ```json Response theme={null} { "prompt": "What is the best web scraping API for e-commerce data?", "brand": "ScrapeBadger", "domain": "scrapebadger.com", "mentioned": true, "mention_count": 2, "first_position": 118, "position_score": 0.72, "share_of_voice_pct": 33.3, "cited": true, "cited_urls": ["https://scrapebadger.com/amazon"], "citation_rank": 2, "competitors": [ { "name": "Bright Data", "mentioned": true, "mention_count": 3, "first_position": 41, "cited": true, "cited_urls": ["https://brightdata.com/products/web-scraper"] }, { "name": "Oxylabs", "mentioned": true, "mention_count": 1, "first_position": 268, "cited": false, "cited_urls": [] }, { "name": "Zyte", "mentioned": false, "mention_count": 0, "first_position": null, "cited": false, "cited_urls": [] } ], "excerpt": "...for structured e-commerce data specifically, ScrapeBadger offers dedicated Amazon and eBay endpoints with per-request credit pricing, which avoids the proxy-bandwidth billing model...", "answer": "For e-commerce scraping in 2026 the strongest options are Bright Data, ScrapeBadger and Oxylabs. Bright Data has the widest proxy footprint, but for structured e-commerce data specifically, ScrapeBadger offers dedicated Amazon and eBay endpoints with per-request credit pricing, which avoids the proxy-bandwidth billing model. Oxylabs sits between the two on price.", "citations": [ { "url": "https://brightdata.com/products/web-scraper", "title": "Web Scraper API", "snippet": "Collect public web data at scale with our unblocking infrastructure...", "domain": "brightdata.com", "attribution": "Bright Data", "pub_date_utc": null, "published_at": null, "start_index": 84, "end_index": 132, "matched_text": "Bright Data has the widest proxy footprint" }, { "url": "https://scrapebadger.com/amazon", "title": "Amazon Scraper API", "snippet": "Product search, PDP detail, offers, reviews and bestsellers across 20 marketplaces...", "domain": "scrapebadger.com", "attribution": "ScrapeBadger", "pub_date_utc": null, "published_at": null, "start_index": 178, "end_index": 322, "matched_text": "ScrapeBadger offers dedicated Amazon and eBay endpoints with per-request credit pricing, which avoids the proxy-bandwidth billing model" } ], "web_search_triggered": true, "model": "gpt-5-5", "country": "US", "latency_ms": 27342, "created_utc": 1754323200.0, "created_at": "2026-08-04T16:00:00Z" } ``` `position_score` is the single number to trend over time: `1.0` means the brand was named at the very start of the answer, `0.0` means it was absent. Combine it with `share_of_voice_pct` and `cited` for a full picture. Because ChatGPT is non-deterministic, one call is a sample, not a measurement. Run the same prompt on a schedule (daily, or several times a day for competitive prompts) and track the moving average of `position_score` and `share_of_voice_pct`. Vary `country` to see how visibility differs by market. # List Models Source: https://docs.scrapebadger.com/api-reference/endpoint/chatgpt/list-models GET https://scrapebadger.com/v1/chatgpt/models Read the catalogue of models chatgpt.com currently exposes, with slugs, descriptions, token limits and tags. Return the model catalogue `chatgpt.com` currently advertises. Useful for interpreting the `model` field on an [`/ask`](/api-reference/endpoint/chatgpt/ask) response and for tracking when OpenAI rotates its lineup. **Credits:** 1 This is a **read-only catalogue**. You cannot select a model for `/ask` or `/brand-visibility` — the `model` field in those responses reports which model answered, it is not a request parameter. ## Authorization Your ScrapeBadger API key. ## Query Parameters ISO-3166 alpha-2 egress country. The advertised lineup can differ by market. ## Response The models chatgpt.com currently lists. Model identifier, e.g. `gpt-5-5`. Matches the `model` field on an answer. Human-readable name as shown in the ChatGPT model picker. Short description of what the model is for. Context limit advertised for the model. Labels ChatGPT attaches to the model, e.g. `default`, `reasoning`. Number of entries in `models`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/chatgpt/models?country=US" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/chatgpt/models?" + new URLSearchParams({ country: "US" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); console.log(data.models.map((m) => m.slug)); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/chatgpt/models", headers={"X-API-Key": "YOUR_API_KEY"}, params={"country": "US"}, ) data = res.json() print([m["slug"] for m in data["models"]]) ``` ```json Response theme={null} { "models": [ { "slug": "auto", "title": "Auto", "description": "Picks the best model for the question.", "max_tokens": 32000, "tags": ["default"] }, { "slug": "gpt-5-5", "title": "GPT-5.5", "description": "Great for most questions.", "max_tokens": 32000, "tags": [] }, { "slug": "gpt-5-5-mini", "title": "GPT-5.5 mini", "description": "Faster responses for everyday tasks.", "max_tokens": 32000, "tags": [] }, { "slug": "gpt-5-3", "title": "GPT-5.3", "description": "Previous generation model.", "max_tokens": 32000, "tags": ["legacy"] }, { "slug": "gpt-5-3-mini", "title": "GPT-5.3 mini", "description": "Previous generation, faster variant.", "max_tokens": 32000, "tags": ["legacy"] } ], "count": 5 } ``` The lineup changes whenever OpenAI ships or retires a model. Slugs seen live at the time of writing: `auto`, `gpt-5-5`, `gpt-5-5-mini`, `gpt-5-3`, `gpt-5-3-mini`. Read the catalogue rather than hard-coding slugs. # Get Community Details Source: https://docs.scrapebadger.com/api-reference/endpoint/communities/get-community-details get /v1/twitter/communities/{community_id} Get detailed information about a Twitter community. Returns comprehensive community data including name, description, member count, join policy, banner image, creator/admin info, and community rules. Useful for understanding a community before exploring its content. # Get Community Tweets Source: https://docs.scrapebadger.com/api-reference/endpoint/communities/get-community-tweets get /v1/twitter/communities/{community_id}/tweets Get tweets from a specific community. Returns tweets posted within the community, filterable by type (Top, Latest, or Media). Supports pagination for communities with extensive content. # Search Communities Source: https://docs.scrapebadger.com/api-reference/endpoint/communities/search-communities get /v1/twitter/communities/search Search for Twitter communities by name, description, or keywords. Returns matching communities with comprehensive information including member count, join policy, and description. Useful for discovering communities related to specific topics. # Get Product Source: https://docs.scrapebadger.com/api-reference/endpoint/depop/get-product GET /v1/depop/products/{slug} Full detail for a single Depop item — title, description, brand, condition, price, images, and seller. ## Path Parameters The Depop item slug. You can find this in search results (`slug`) or extract it from a product URL (`https://www.depop.com/products/{slug}/`). ## Query Parameters Which market to render the item in — selects the country and currency. See [`/v1/depop/markets`](/api-reference/endpoint/depop/list-markets) for the full list. ## Response Depop item id (nullable). Item slug (nullable). Item title (nullable). Full item description (nullable). Brand name (nullable). Item condition, e.g. `Brand new`, `Used - excellent` (nullable). Current price in the market's currency (nullable). ISO 4217 currency code (nullable). Availability status, e.g. `in_stock`, `sold` (nullable). Seller's average dispatch estimate as shown on the listing, e.g. `3 days`, `24 hours` (nullable — not every seller has one). Username of the seller (nullable). Item photo URLs. Full URL to the item (nullable). ### Example Response ```json theme={null} { "id": "123456789", "slug": "seller123-nike-air-max-90-uk-9", "title": "Nike Air Max 90 — UK 9", "description": "Worn a handful of times, great condition. No box.", "brand": "Nike", "condition": "Used - excellent", "price": 65.0, "currency": "USD", "availability": "in_stock", "dispatch_time": "3 days", "seller_username": "seller123", "images": [ "https://media-photos.depop.com/b1/12345/photo-1.jpg", "https://media-photos.depop.com/b1/12345/photo-2.jpg" ], "url": "https://www.depop.com/products/seller123-nike-air-max-90-uk-9/" } ``` Each product-detail request costs **10 credits**. Failed requests are not charged. # Get User Source: https://docs.scrapebadger.com/api-reference/endpoint/depop/get-user GET /v1/depop/users/{username} Full Depop shop profile — display name, bio, rating, and follower count. ## Path Parameters The seller's Depop username, e.g. `seller123`. Take it from the `seller_username` field of any item card or product detail. ## Query Parameters Which market to render the profile in — selects the country and currency context. See [`/v1/depop/markets`](/api-reference/endpoint/depop/list-markets) for the full list. ## Response The seller's username (nullable). Display name (nullable). Shop bio / description (nullable). Average seller rating, e.g. `4.8` (nullable). Number of ratings the seller has received (nullable). Number of followers (nullable). Full URL to the shop profile (nullable). ### Example Response ```json theme={null} { "username": "seller123", "name": "Vintage Finds", "description": "Curated vintage streetwear. Ships worldwide. UK based.", "rating_value": 4.8, "rating_count": 312, "follower_count": 5400, "url": "https://www.depop.com/seller123/" } ``` Each user-profile request costs **10 credits**. Failed requests are not charged. # Get User Products Source: https://docs.scrapebadger.com/api-reference/endpoint/depop/get-user-products GET /v1/depop/users/{username}/products List the items a Depop seller has listed for sale. ## Path Parameters The seller's Depop username, e.g. `seller123`. ## Query Parameters Which market to render the items in — selects the country and currency. See [`/v1/depop/markets`](/api-reference/endpoint/depop/list-markets) for the full list. Number of items per page. Range: `1` - `24`. Page number for paginated results (page-based pagination). ## Response The seller's username. Array of the seller's item cards. Item slug (the path segment used by [`/v1/depop/products/{slug}`](/api-reference/endpoint/depop/get-product)) (nullable). Full URL to the item (nullable). Username of the seller (nullable). Brand name (nullable). Item size as displayed (nullable). Current price in the market's currency (nullable). Original price before markdown; `null` if not discounted. ISO 4217 currency code (nullable). Whether the item has been sold (nullable). Primary item photo URL (nullable). Pagination info. Number of items returned on this page. Current page number. Whether more pages are available. The market the items were rendered in. ### Example Response ```json theme={null} { "username": "seller123", "products": [ { "slug": "seller123-nike-air-max-90-uk-9", "url": "https://www.depop.com/products/seller123-nike-air-max-90-uk-9/", "seller_username": "seller123", "brand": "Nike", "size": "UK 9", "price": 65.0, "original_price": 90.0, "currency": "USD", "is_sold": false, "image": "https://media-photos.depop.com/b1/12345/photo.jpg" } ], "meta": { "result_count": 24, "page": 1, "has_more": true }, "market": "us" } ``` Each user-products request costs **10 credits**. Failed requests are not charged. # List Markets Source: https://docs.scrapebadger.com/api-reference/endpoint/depop/list-markets GET /v1/depop/markets List all supported Depop markets with their country codes and currencies. ## Response Array of supported markets. Market code to use in the `market` query parameter (e.g. `us`, `gb`, `au`). ISO 3166-1 alpha-2 country code. ISO 4217 currency code used in this market. Market country name. ### Example Response ```json theme={null} { "markets": [ { "code": "us", "country_code": "US", "currency": "USD", "name": "United States" }, { "code": "gb", "country_code": "GB", "currency": "GBP", "name": "United Kingdom" }, { "code": "au", "country_code": "AU", "currency": "AUD", "name": "Australia" }, { "code": "ie", "country_code": "IE", "currency": "EUR", "name": "Ireland" }, { "code": "it", "country_code": "IT", "currency": "EUR", "name": "Italy" }, { "code": "fr", "country_code": "FR", "currency": "EUR", "name": "France" }, { "code": "de", "country_code": "DE", "currency": "EUR", "name": "Germany" }, { "code": "es", "country_code": "ES", "currency": "EUR", "name": "Spain" }, { "code": "nl", "country_code": "NL", "currency": "EUR", "name": "Netherlands" }, { "code": "nz", "country_code": "NZ", "currency": "NZD", "name": "New Zealand" } ] } ``` Listing markets is a **free** reference endpoint (0 credits). # Search Items Source: https://docs.scrapebadger.com/api-reference/endpoint/depop/search-items GET /v1/depop/search Search Depop for second-hand fashion items — filter by price, brand, size, colour, condition, and gender. ## Query Parameters Free-text search query, e.g. `nike air max`, `vintage levis`, `carhartt jacket`. Which market to search. Depop runs on a single global host (`www.depop.com`) localised by market — this selects the country and currency of the results. See [`/v1/depop/markets`](/api-reference/endpoint/depop/list-markets) for the full list. Number of items per page. Range: `1` - `24`. Page number for paginated results (page-based pagination). Minimum price in the market's local currency. Maximum price in the market's local currency. Comma-separated brand filters, e.g. `nike,adidas`. Comma-separated size filters, e.g. `m,l` or `uk-10`. Comma-separated colour filters, e.g. `black,green`. Comma-separated condition filters, e.g. `brand_new,used_excellent`. Gender department filter, e.g. `menswear`, `womenswear`. Result ordering: `relevance` (default), `priceAscending` or `priceDescending`. Any other value returns `422`. Depop removed sort-by-newest from its search in September 2026 — `newlyListed` is no longer accepted and there is no equivalent. To watch new listings, poll [`/v1/depop/users/{username}/products`](/api-reference/endpoint/depop/get-user-products), which returns a seller's listings newest-first. ## Response Array of matching item cards. Item slug (the path segment used by [`/v1/depop/products/{slug}`](/api-reference/endpoint/depop/get-product)) (nullable). Full URL to the item (nullable). Username of the seller (nullable). Brand name (nullable). Item size as displayed (nullable). Current price in the market's currency (nullable). Original price before markdown; `null` if not discounted. ISO 4217 currency code (nullable). Whether the item has been sold (nullable). Primary item photo URL (nullable). Pagination info. Number of items returned on this page. Current page number. Whether more pages are available. The market that was searched. The query that was searched. ### Example Response ```json theme={null} { "products": [ { "slug": "seller123-nike-air-max-90-uk-9", "url": "https://www.depop.com/products/seller123-nike-air-max-90-uk-9/", "seller_username": "seller123", "brand": "Nike", "size": "UK 9", "price": 65.0, "original_price": 90.0, "currency": "USD", "is_sold": false, "image": "https://media-photos.depop.com/b1/12345/photo.jpg" } ], "meta": { "result_count": 24, "page": 1, "has_more": true }, "market": "us", "query": "nike air max" } ``` Each search request costs **10 credits**. Failed requests are not charged. # Autocomplete Source: https://docs.scrapebadger.com/api-reference/endpoint/duckduckgo/autocomplete GET https://scrapebadger.com/v1/duckduckgo/autocomplete Get DuckDuckGo search-box suggestions for a partial query. Get DuckDuckGo's search-box suggestions for a partial query. Region-aware. **Credits:** 1 ## Authorization Your ScrapeBadger API key. ## Query Parameters Partial query to complete, e.g. `web scra`. DuckDuckGo region code (`kl`), e.g. `us-en`. `wt-wt` = all regions. ## Response Echo of the requested query. Suggested queries, in DuckDuckGo's order. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/duckduckgo/autocomplete?query=web+scra" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/duckduckgo/autocomplete?" + new URLSearchParams({ query: "web scra" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { suggestions } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/duckduckgo/autocomplete", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "web scra"}, ) suggestions = res.json()["suggestions"] ``` ```json Response theme={null} { "query": "web scra", "suggestions": [ "web scraping", "web scraping python", "web scraping tools", "web scraping api", "web scraper chrome extension" ] } ``` Autocomplete costs 1 credit — expand a partial term into real DuckDuckGo queries here, then run [`/search`](/api-reference/endpoint/duckduckgo/search) on each one. # Image Search Source: https://docs.scrapebadger.com/api-reference/endpoint/duckduckgo/images GET https://scrapebadger.com/v1/duckduckgo/images Search DuckDuckGo images with size, color, type, layout and license filters. Search DuckDuckGo images. 100 results per page. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search query, e.g. `sunset`. DuckDuckGo region code (`kl`), e.g. `us-en`. `wt-wt` = all regions. One of `on`, `moderate`, `off`. Result page, `1`–`10`. 100 results per page. `Small`, `Medium`, `Large` or `Wallpaper`. `color`, `Monochrome`, or a named color such as `Red`, `Blue`, `Green`. `photo`, `clipart`, `gif`, `transparent` or `line`. `Square`, `Tall` or `Wide`. `Any`, `Public`, `Share`, `ShareCommercially` or `Modify`. ## Response Echo of the requested query. The region that was applied. Image results. Full-size image URL. The page the image was found on. The index the result came from, e.g. `Bing`. e.g. `jpeg`, `png`. Results on this page. Page on this. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/duckduckgo/images?query=sunset&size=Large&layout=Wide" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/duckduckgo/images?" + new URLSearchParams({ query: "sunset", size: "Large", layout: "Wide", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/duckduckgo/images", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "query": "sunset", "size": "Large", "layout": "Wide", }, ) data = res.json() ``` ```json Response theme={null} { "query": "sunset", "region": "wt-wt", "results": [ { "title": "Beautiful Sunset Over the Ocean", "image": "https://example.com/images/sunset-4k.jpg", "thumbnail": "https://tse1.mm.bing.net/th?id=OIP.abc123", "url": "https://example.com/gallery/sunset", "width": 3840, "height": 2160, "source": "Bing", "encoding_format": "jpeg", "discovery_date": "2026-07-14T00:00:00.0000000" } ], "result_count": 100, "has_next": true } ``` # Instant Answer Source: https://docs.scrapebadger.com/api-reference/endpoint/duckduckgo/instant GET https://scrapebadger.com/v1/duckduckgo/instant Query the DuckDuckGo Instant Answer API — abstract, definition, direct answer, related topics. Query the DuckDuckGo Instant Answer API. Best for reference queries — entities, people, places, definitions and calculations. **Credits:** 1 Instant Answers are **entity-shaped**: most long-tail search phrases return an empty payload. That is DuckDuckGo's behaviour, not an error — use [`/search`](/api-reference/endpoint/duckduckgo/search) for general queries. ## Authorization Your ScrapeBadger API key. ## Query Parameters Query for the Instant Answer API, e.g. `Nikola Tesla`. ## Response Echo of the requested query. Abstract, may contain HTML. Abstract as plain text. e.g. `Wikipedia`. The topic name. Direct answer for calculation/conversion queries. e.g. `calc`, `ip`, `color_code`. Dictionary definition, when applicable. Answer category: `A` (article), `D` (disambiguation), `C` (category), `N` (name), `E` (exclusive). Set for `!bang` redirect queries. Related topics. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/duckduckgo/instant?query=Nikola+Tesla" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/duckduckgo/instant?" + new URLSearchParams({ query: "Nikola Tesla" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/duckduckgo/instant", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "Nikola Tesla"}, ) data = res.json() ``` ```json Response theme={null} { "query": "Nikola Tesla", "abstract": "Nikola Tesla was a Serbian-American inventor, electrical engineer...", "abstract_text": "Nikola Tesla was a Serbian-American inventor, electrical engineer...", "abstract_source": "Wikipedia", "abstract_url": "https://en.wikipedia.org/wiki/Nikola_Tesla", "heading": "Nikola Tesla", "answer": "", "answer_type": "", "definition": "", "definition_source": "", "definition_url": "", "image": "/i/ee2712bd.jpg", "type": "A", "redirect": "", "related_topics": [ { "text": "Wardenclyffe Tower - An early experimental wireless transmission station...", "url": "https://duckduckgo.com/Wardenclyffe_Tower", "icon": null } ] } ``` # News Search Source: https://docs.scrapebadger.com/api-reference/endpoint/duckduckgo/news GET https://scrapebadger.com/v1/duckduckgo/news Search DuckDuckGo news — headline, source, excerpt, Unix + ISO dates, image. Search DuckDuckGo news. 30 results per page. Every date ships in both forms: `date_utc` (Unix seconds) and `date_at` (ISO 8601 UTC string). **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search query, e.g. `artificial intelligence`. DuckDuckGo region code (`kl`), e.g. `us-en`. `wt-wt` = all regions. One of `on`, `moderate`, `off`. Restrict result age: `day`, `week`, `month` or `year`. Omit for all time. Result page, `1`–`10`. 30 results per page. ## Response Echo of the requested query. The region that was applied. News results. Publisher, e.g. `Reuters`. DuckDuckGo's own label, e.g. `2 hours ago`. Publication time as Unix seconds. Publication time as an ISO 8601 UTC string. The aggregator DuckDuckGo sourced from, e.g. `Bing`. Results on this page. Page on this. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/duckduckgo/news?query=artificial+intelligence&timelimit=week" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/duckduckgo/news?" + new URLSearchParams({ query: "artificial intelligence", timelimit: "week", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/duckduckgo/news", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "query": "artificial intelligence", "timelimit": "week", }, ) data = res.json() ``` ```json Response theme={null} { "query": "artificial intelligence", "region": "wt-wt", "results": [ { "title": "AI breakthrough announced by research lab", "url": "https://www.reuters.com/technology/ai-breakthrough", "excerpt": "Researchers announced a new artificial intelligence model that...", "source": "Reuters", "image": "https://www.reuters.com/resizer/image.jpg", "relative_time": "2 hours ago", "date_utc": 1754640000, "date_at": "2026-08-08T08:00:00Z", "syndicate": "Bing" } ], "result_count": 30, "has_next": true } ``` # List Regions Source: https://docs.scrapebadger.com/api-reference/endpoint/duckduckgo/regions GET https://scrapebadger.com/v1/duckduckgo/regions List all supported DuckDuckGo region (kl) codes. List every DuckDuckGo region (`kl`) code accepted by the `region` parameter. This endpoint is **free**. **Credits:** 0 ## Authorization Your ScrapeBadger API key. ## Response Supported regions, in DuckDuckGo's own order. The `kl` code, e.g. `us-en`. `wt-wt` = All Regions. Human label, e.g. `United States`. Number of regions. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/duckduckgo/regions" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch("https://scrapebadger.com/v1/duckduckgo/regions", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY }, }); const { regions } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/duckduckgo/regions", headers={"X-API-Key": "YOUR_API_KEY"}, ) regions = res.json()["regions"] ``` ```json Response theme={null} { "regions": [ { "code": "wt-wt", "name": "All Regions" }, { "code": "ar-es", "name": "Argentina" }, { "code": "au-en", "name": "Australia" }, { "code": "us-en", "name": "United States" } ], "count": 64 } ``` # Web Search Source: https://docs.scrapebadger.com/api-reference/endpoint/duckduckgo/search GET https://scrapebadger.com/v1/duckduckgo/search Search the DuckDuckGo web SERP — organic results, the zero-click abstract box, ads flagged. Search the DuckDuckGo web SERP. Ad results are returned and flagged `is_ad`; the zero-click abstract box is attached when DuckDuckGo shows one. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search query, e.g. `web scraping`. DuckDuckGo region code (`kl`), e.g. `us-en`, `uk-en`, `de-de`. `wt-wt` = all regions. List every code with [`/regions`](/api-reference/endpoint/duckduckgo/regions). One of `on`, `moderate`, `off`. Restrict result age: `day`, `week`, `month` or `year`. Omit for all time. Result page, `1`–`25`. ## Response Echo of the requested query. The region that was applied. Organic results plus flagged ads. `true` for ad results — filter on this to keep organic only. The zero-click / instant-answer box above the organic results, when shown. e.g. `Wikipedia`. Results on this page. Page on this. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/duckduckgo/search?query=web+scraping®ion=us-en" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/duckduckgo/search?" + new URLSearchParams({ query: "web scraping", region: "us-en", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/duckduckgo/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "query": "web scraping", "region": "us-en", }, ) data = res.json() ``` ```json Response theme={null} { "query": "web scraping", "region": "us-en", "results": [ { "title": "Web scraping - Wikipedia", "url": "https://en.wikipedia.org/wiki/Web_scraping", "snippet": "Web scraping, web harvesting, or web data extraction is data scraping used for extracting data from websites...", "display_url": "en.wikipedia.org/wiki/Web_scraping", "is_ad": false } ], "abstract": { "heading": "Web scraping", "text": "Web scraping, web harvesting, or web data extraction is data scraping used for extracting data from websites.", "url": "https://en.wikipedia.org/wiki/Web_scraping", "image": null, "source": "Wikipedia" }, "result_count": 24, "has_next": true } ``` # Video Search Source: https://docs.scrapebadger.com/api-reference/endpoint/duckduckgo/videos GET https://scrapebadger.com/v1/duckduckgo/videos Search DuckDuckGo videos — title, publisher, uploader, duration, views, thumbnails. Search DuckDuckGo videos. 60 results per page. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search query, e.g. `python tutorial`. DuckDuckGo region code (`kl`), e.g. `us-en`. `wt-wt` = all regions. One of `on`, `moderate`, `off`. Result page, `1`–`10`. 60 results per page. `short`, `medium` or `long`. `high` or `standard`. ## Response Echo of the requested query. The region that was applied. Video results. The watch URL. e.g. `10:23`. e.g. `YouTube`. The channel or account name. ISO 8601 publication time. Thumbnail URLs keyed by size, e.g. `small`, `medium`, `large`, `motion`. Results on this page. Page on this. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/duckduckgo/videos?query=python+tutorial&duration=long" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/duckduckgo/videos?" + new URLSearchParams({ query: "python tutorial", duration: "long", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/duckduckgo/videos", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "query": "python tutorial", "duration": "long", }, ) data = res.json() ``` ```json Response theme={null} { "query": "python tutorial", "region": "wt-wt", "results": [ { "title": "Python Full Course for Beginners", "content": "https://www.youtube.com/watch?v=abc123", "description": "Learn Python from scratch in this complete course...", "duration": "4:26:52", "publisher": "YouTube", "uploader": "Programming with Mosh", "published_at": "2026-01-15T14:00:00.0000000", "view_count": 12345678, "images": { "small": "https://tse1.mm.bing.net/th?id=OVP.small", "medium": "https://tse1.mm.bing.net/th?id=OVP.medium", "large": "https://tse1.mm.bing.net/th?id=OVP.large" }, "embed_url": "https://www.youtube.com/embed/abc123" } ], "result_count": 60, "has_next": true } ``` # Keyword Suggestions Source: https://docs.scrapebadger.com/api-reference/endpoint/ebay/autocomplete GET /v1/ebay/autocomplete eBay keyword autocomplete suggestions for a partial query. ## Query Parameters Partial query prefix to autocomplete (e.g. `ninten`). eBay marketplace domain to source suggestions from. Examples: `com`, `co.uk`, `de`, `fr` ## Response The query prefix that was autocompleted. Marketplace domain the suggestions came from. Array of suggestion objects. A suggested search term. ### Example Response ```json theme={null} { "query": "ninten", "domain": "com", "suggestions": [ { "value": "nintendo switch" }, { "value": "nintendo switch oled" }, { "value": "nintendo ds" }, { "value": "nintendo 64" } ] } ``` Each autocomplete request costs **1 credit**. Failed requests are not charged. # Browse a Category Source: https://docs.scrapebadger.com/api-reference/endpoint/ebay/browse-category GET /v1/ebay/categories/{category_id}/items List active listings within an eBay category. ## Path Parameters The eBay category id to browse. Use [`/v1/ebay/categories`](/api-reference/endpoint/ebay/list-categories) to look up ids. ## Query Parameters eBay marketplace domain to browse. Examples: `com`, `co.uk`, `de`, `fr` Page number for paginated results. Range: `1` - `100`. Results per page. Clamped to one of `60`, `120`, or `240`. Sort order for results. | Value | Description | | - | - | | `best_match` | Best match (default) | | `ending_soonest` | Auctions ending soonest first | | `newly_listed` | Most recently listed | | `price_low_to_high` | Cheapest first | | `price_high_to_low` | Most expensive first | Minimum price filter in the marketplace's local currency. Maximum price filter in the marketplace's local currency. ## Response Marketplace domain that was browsed. The category id that was browsed. Array of listings in the category (same `SearchResult` shape as [search](/api-reference/endpoint/ebay/search)). Position on the page (1-based). eBay listing item id. Listing title. Full URL to the listing. Primary image URL. Price object with `value`, `currency`, `symbol`, `raw`. Item condition label. `Buy It Now`, `Auction`, or `Best Offer`. Whether the listing is an auction. Number of bids (auctions only, nullable). Relative time remaining, e.g. `12h 16m` (auctions only, nullable). Current high bid for auction listings with `value`, `currency`, `symbol`, `raw`; mirrors `price`. Null for non-auction (fixed-price) listings. Shipping text. Seller username (nullable). Always `null`. eBay renders its "Sponsored" badge into every card as anti-scraping bait, so promoted placements cannot be distinguished from organic results. Available filter facets keyed by name. Pagination metadata with `current_page`, `per_page`, `total_pages`, `total_results`. ISO 8601 timestamp when the results were scraped. ### Example Response ```json theme={null} { "domain": "com", "category_id": "139971", "results": [ { "position": 1, "item_id": "256123456789", "title": "Nintendo Switch OLED Model White Console - Brand New Sealed", "url": "https://www.ebay.com/itm/256123456789", "image": "https://i.ebayimg.com/images/g/abc/s-l500.jpg", "price": { "value": 299.99, "currency": "USD", "symbol": "$", "raw": "$299.99" }, "condition": "Brand New", "buying_format": "Buy It Now", "is_auction": false, "shipping": "Free shipping", "seller_name": "topgames_us", "is_sponsored": null } ], "facets": { "condition": ["New", "Used"] }, "pagination": { "current_page": 1, "per_page": 60, "total_pages": 100, "total_results": 6000 }, "scraped_at": "2026-06-21T12:00:00Z" } ``` Each category-browse request costs **5 credits**. Failed requests are not charged. # Completed / Sold Listings Source: https://docs.scrapebadger.com/api-reference/endpoint/ebay/completed GET /v1/ebay/completed Search eBay completed (sold) listings — the closing prices buyers actually paid. The completed-listings endpoint returns **sold** items — the closing prices buyers actually paid, with the date each item sold. Every result has `sold` set to `true` on the response envelope. This is the data resellers, flippers and pricing tools rely on, since asking prices alone don't reflect what items actually sell for. ## Query Parameters Search keywords. Matches against listing titles. eBay marketplace domain TLD or alias. See [`/v1/ebay/markets`](/api-reference/endpoint/ebay/list-markets) for all supported values. Examples: `com`, `co.uk`, `de`, `fr`, `com.au` Restrict results to an eBay category id. Use [`/v1/ebay/categories`](/api-reference/endpoint/ebay/list-categories) to look up ids. Page number for paginated results. Range: `1` - `1000`. Use `pagination.has_more` to know when to stop — eBay re-serves its last page if you ask past the end, so this API returns an empty page there. Results per page. Clamped to one of `60`, `120`, or `240`. Sort order for results. | Value | Description | | - | - | | `best_match` | Best match (default) | | `ending_soonest` | Ended soonest first | | `newly_listed` | Most recently ended | | `price_low_to_high` | Lowest sold price first | | `price_high_to_low` | Highest sold price first | Item condition filter (`new`, `open_box`, `refurbished`, `used`, `for_parts`). Trading cards also accept `graded` and `ungraded` — eBay's card conditions for slabbed (PSA / BGS / CGC) versus raw cards. Pricing a raw card against sales that include slabs skews the average badly, so price the two separately. Item location. | Value | Description | | - | - | | `domestic` | Only items located in this marketplace's own country (`domain=fr` → France only) | | `worldwide` | Items from every country | Omit it and you get eBay's default, which mixes foreign listings into a national marketplace. Two things follow from that, and both matter for price research: a national price series picks up sales that never happened in that country, and a foreign listing's price is shown **converted** into the marketplace's currency rather than the amount it actually sold for. `location=domestic` removes both. Minimum sold-price filter in the marketplace's local currency. Maximum sold-price filter in the marketplace's local currency. ## Response Identical shape to [`/v1/ebay/search`](/api-reference/endpoint/ebay/search), except `sold` is `true`, each result's `price` reflects the **final sold price**, and each result carries a `sold_date`. The search query that was executed. Marketplace domain that was searched. Always `true` for completed/sold listings. Array of sold listings (same `SearchResult` shape as active search). Position on the page (1-based). eBay listing item id. Listing title. Full URL to the listing. Primary image URL. Final **sold** price with `value`, `currency`, `symbol`, `raw`. Item condition label. `Buy It Now`, `Auction`, or `Best Offer`. Whether the listing was an auction. Number of bids the auction received (nullable). Winning bid for auction listings with `value`, `currency`, `symbol`, `raw`; mirrors `price`. Null for fixed-price listings. Shipping text. Item location text. Sale date text as rendered by eBay, e.g. `Aug 19, 2026`. Localized on non-English marketplaces (e.g. `Verkauft 5. Okt. 2024`), nullable. Best-effort ISO date parsed from `sold_date`, e.g. `2026-08-19`. Null when the marketplace's date format is not English. Seller username (nullable). Always `null`. eBay renders its "Sponsored" badge into every card as anti-scraping bait, so promoted placements cannot be distinguished from organic results. Available filter facets keyed by name. Pagination metadata with `current_page`, `per_page`, `total_results`, `has_more`. `total_results` is populated (the sold results page carries a match count). `total_pages` may be `null` — page with `has_more` rather than a fixed page total. ISO 8601 timestamp when the results were scraped. ### Example Response ```json theme={null} { "query": "nintendo switch", "domain": "com", "sold": true, "results": [ { "position": 1, "item_id": "256987654321", "title": "Nintendo Switch (OLED Model) - Used", "url": "https://www.ebay.com/itm/256987654321", "image": "https://i.ebayimg.com/images/g/xyz/s-l500.jpg", "price": { "value": 260.0, "currency": "USD", "symbol": "$", "raw": "$260.00" }, "condition": "Pre-Owned", "buying_format": "Auction", "is_auction": true, "bids": 14, "current_bid": { "value": 260.0, "currency": "USD", "symbol": "$", "raw": "$260.00" }, "shipping": "Free shipping", "location": "United States", "sold_date": "Aug 19, 2026", "sold_date_at": "2026-08-19", "seller_name": "gamerdeals99", "is_sponsored": null } ], "facets": {}, "pagination": { "current_page": 1, "per_page": 60, "total_pages": null, "total_results": 34000, "has_more": true }, "scraped_at": "2026-08-20T12:00:00Z" } ``` ## Fetching every sold listing `has_more` is the stop signal for bulk extraction. Increment `page` while it is `true`: ```python theme={null} page, all_sold = 1, [] while True: r = requests.get( "https://scrapebadger.com/v1/ebay/completed", params={"query": "iphone 13", "per_page": 240, "page": page}, headers={"X-API-Key": API_KEY}, ).json() all_sold += r["results"] if not r["results"] or not r["pagination"]["has_more"]: break page += 1 ``` Do not loop on "until the response is empty" alone. Past its last page eBay **clamps** — asking for page 200 of a 133-page result set re-serves page 133. This API detects that and returns an empty page with `has_more: false`, but a client that ignores `has_more` and retries forever will keep spending credits. A broad sold search runs roughly 130 pages deep at `per_page=240` (\~26,000 listings). Use the largest `per_page` you can: each request costs 5 credits regardless of page size, so `per_page=240` is about 8x cheaper per listing than the default. Each completed/sold request costs **5 credits**. Failed requests are not charged. # Get Item Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/ebay/get-item-detail GET /v1/ebay/items/{item_id} Full detail for a single eBay listing (price, condition, specifics, shipping, seller, ...). ## Path Parameters The eBay listing item id. You can find this in search results or extract it from a listing URL (`/itm/{item_id}`). ## Query Parameters eBay marketplace domain where the listing lives. Examples: `com`, `co.uk`, `de`, `fr` ## Response Marketplace domain the item was fetched from. Full item object. eBay listing item id. eBay catalog product id (nullable). Legacy item id, if different (nullable). Listing title. Listing subtitle (nullable). Full URL to the listing. Item condition label. eBay numeric condition id (nullable). Seller's free-text condition note (nullable). Current price with `value`, `currency`, `symbol`, `raw`. Strikethrough original price (nullable). Discount percentage off original price (nullable). ISO 4217 currency code. Availability/stock message. Quantity available (nullable). Quantity sold (nullable). Number of watchers (nullable). `Buy It Now`, `Auction`, or `Best Offer`. Whether the listing is an auction. Number of bids (auctions only, nullable). Relative time remaining for auctions, e.g. `12h 16m` (auctions only, nullable). Current high bid for auction listings with `value`, `currency`, `symbol`, `raw`; mirrors `price`. Null for non-auction (fixed-price) listings. `true` when the listing has closed (sold or ended), any buying format. Defaults to `false`. Listing end time as a Unix timestamp (float seconds): the auction close time, or the exact sold/ended time for ended listings of any format. Null for active fixed-price listings. Listing end time as an ISO-8601 UTC string, e.g. `2026-06-22T19:50:51Z`: the auction close time, or the exact sold/ended time for ended listings of any format (nullable). Buy It Now price for fixed-price listings (mirrors `price`) or auction-with-Buy-It-Now listings, with `value`, `currency`, `symbol`, `raw`. Null for pure auctions. Whether the seller accepts best offers (nullable). Brand name (nullable). Manufacturer part number (nullable). Model name (nullable). Color (nullable). GTIN/UPC/EAN (nullable). Primary image URL. All image objects with `url`, `width`, `height`. Number of images. Listing description text (nullable). Seller notes (nullable). Key-value map of item specifics (e.g. `{"Brand": "Nintendo"}`). Category breadcrumb path. Primary category id (nullable). Shipping options with `cost`, `is_free`, `service`, `destination_country`, `delivery_estimate`. Primary shipping cost (nullable). Whether primary shipping is free (nullable). Item location text. List of destinations the seller ships to. Returns policy with `accepted`, `period`, `cost_paid_by`, `raw`. Seller summary with `username`, `url`, `feedback_score`, `feedback_percent`, `store_name`, `store_url`. Catalog rating, if shown (nullable). Total ratings, if shown (nullable). ISO 8601 timestamp the listing was last modified (nullable). ISO 8601 timestamp when the item was scraped. ### Example Response ```json theme={null} { "domain": "com", "item": { "item_id": "256123456789", "product_id": "20057872541", "title": "Nintendo Switch OLED Model White Console - Brand New Sealed", "url": "https://www.ebay.com/itm/256123456789", "condition": "Brand New", "condition_id": "1000", "price": { "value": 299.99, "currency": "USD", "symbol": "$", "raw": "$299.99" }, "currency": "USD", "availability": "In Stock", "quantity_available": 12, "quantity_sold": 42, "watchers": 18, "buying_format": "Buy It Now", "is_auction": false, "bids": null, "time_left": null, "current_bid": null, "is_ended": false, "end_time_utc": null, "end_time_at": null, "buy_it_now_price": { "value": 299.99, "currency": "USD", "symbol": "$", "raw": "$299.99" }, "best_offer_enabled": true, "brand": "Nintendo", "mpn": "HEGSKAAAA", "gtin": "0045496883414", "main_image": "https://i.ebayimg.com/images/g/abc/s-l1600.jpg", "images": [{ "url": "https://i.ebayimg.com/images/g/abc/s-l1600.jpg", "width": 1600, "height": 1600 }], "images_count": 1, "item_specifics": { "Brand": "Nintendo", "Model": "Switch OLED", "Color": "White" }, "categories": ["Video Games & Consoles", "Video Game Consoles"], "category_id": "139971", "shipping_options": [{ "cost": { "value": 0, "currency": "USD", "raw": "Free" }, "is_free": true, "service": "Standard Shipping" }], "free_shipping": true, "item_location": "United States", "ships_to": ["United States", "Canada"], "returns": { "accepted": true, "period": "30 days", "cost_paid_by": "buyer", "raw": "30 days returns. Buyer pays return shipping." }, "seller": { "username": "topgames_us", "url": "https://www.ebay.com/usr/topgames_us", "feedback_score": 18452, "feedback_percent": 99.4 }, "scraped_at": "2026-06-21T12:00:00Z" } } ``` ### Auction data Auction listings are fully supported. For auctions, `is_auction` is `true` and the auction-specific fields are populated: `bids` (bid count), `time_left` (relative remaining time), `current_bid` (the current high bid, mirroring `price`), and the absolute end time as both `end_time_utc` (Unix timestamp) and `end_time_at` (ISO-8601 Z string). For pure auctions `buy_it_now_price` is `null`; for fixed-price or auction-with-Buy-It-Now listings it carries the BIN price. For listings that have closed (sold or ended) — any buying format, not just auctions — `is_ended` is `true` and `end_time_utc` / `end_time_at` carry the exact sold/ended time. For active fixed-price listings all three stay at their defaults (`false` / `null` / `null`). ```json theme={null} { "domain": "com", "item": { "item_id": "256987654321", "title": "Vintage Omega Seamaster Automatic Watch - No Reserve", "url": "https://www.ebay.com/itm/256987654321", "condition": "Pre-owned", "price": { "value": 412.0, "currency": "USD", "symbol": "$", "raw": "$412.00" }, "currency": "USD", "buying_format": "Auction", "is_auction": true, "bids": 23, "time_left": "12h 16m", "current_bid": { "value": 412.0, "currency": "USD", "symbol": "$", "raw": "$412.00" }, "is_ended": false, "end_time_utc": 1781034651.0, "end_time_at": "2026-06-22T19:50:51Z", "buy_it_now_price": null, "scraped_at": "2026-06-22T07:34:51Z" } } ``` Each item-detail request costs **5 credits**. Failed requests are not charged. # Get Item Reviews Source: https://docs.scrapebadger.com/api-reference/endpoint/ebay/get-item-reviews GET /v1/ebay/items/{item_id}/reviews Catalog product reviews shown on an eBay listing, with rating summary and histogram. ## Path Parameters The eBay listing item id whose catalog product reviews you want. ## Query Parameters eBay marketplace domain where the listing lives. Examples: `com`, `co.uk`, `de`, `fr` Page number for paginated reviews. Range: `1` - `50`. ## Response Marketplace domain the reviews were fetched from. The item id the reviews were requested for (nullable). The eBay catalog product id the reviews belong to (nullable). Average star rating across all reviews (0-5, nullable). Total number of ratings (nullable). Star-bucket counts. Number of 5-star reviews (nullable). Number of 4-star reviews (nullable). Number of 3-star reviews (nullable). Number of 2-star reviews (nullable). Number of 1-star reviews (nullable). Array of reviews. Review title (nullable). Review body text (nullable). Star rating for this review (0-5, nullable). Reviewer display name (nullable). Raw date string as shown on eBay (nullable). ISO 8601 review date (nullable). Number of helpful votes (nullable). Whether the review is from a verified purchase. Pagination metadata with `current_page`, `per_page`, `total_pages`, `total_results`. ISO 8601 timestamp when the reviews were scraped. ### Example Response ```json theme={null} { "domain": "com", "item_id": "256123456789", "product_id": "20057872541", "rating": 4.8, "ratings_total": 1245, "histogram": { "five_star": 1050, "four_star": 120, "three_star": 40, "two_star": 20, "one_star": 15 }, "reviews": [ { "title": "Excellent console", "body": "Screen is gorgeous and the build quality is great.", "rating": 5.0, "author": "gamer_dad", "date_raw": "May 12, 2026", "date_at": "2026-05-12T00:00:00Z", "helpful_votes": 23, "verified_purchase": true } ], "pagination": { "current_page": 1, "per_page": 20, "total_pages": 50, "total_results": 1245 }, "scraped_at": "2026-06-21T12:00:00Z" } ``` Each item-reviews request costs **10 credits**. Failed requests are not charged. # Get Seller Profile Source: https://docs.scrapebadger.com/api-reference/endpoint/ebay/get-seller GET /v1/ebay/sellers/{username} An eBay seller's public profile, feedback summary, and store info. ## Path Parameters The eBay seller username (e.g. `topgames_us`). ## Query Parameters eBay marketplace domain to resolve the seller on. Examples: `com`, `co.uk`, `de`, `fr` ## Response Marketplace domain the seller was fetched from. Seller profile object. Seller username. URL to the seller's profile page. eBay Store name, if the seller has a store (nullable). URL to the seller's store (nullable). Lifetime feedback score (nullable). Positive-feedback percentage (nullable). Account creation date text (nullable). Seller location (nullable). Number of active listings (nullable). 12-month feedback breakdown. Positive feedback count (nullable). Neutral feedback count (nullable). Negative feedback count (nullable). Whether the seller is a Top Rated Seller (nullable). ISO 8601 timestamp when the seller was scraped. ### Example Response ```json theme={null} { "domain": "com", "seller": { "username": "topgames_us", "url": "https://www.ebay.com/usr/topgames_us", "store_name": "Top Games US", "store_url": "https://www.ebay.com/str/topgamesus", "feedback_score": 18452, "feedback_percent": 99.4, "member_since": "Mar 2014", "location": "United States", "items_for_sale": 1342, "feedback_12mo": { "positive": 9821, "neutral": 41, "negative": 53 }, "top_rated": true, "scraped_at": "2026-06-21T12:00:00Z" } } ``` Each seller-profile request costs **5 credits**. Failed requests are not charged. # Get Seller Feedback Source: https://docs.scrapebadger.com/api-reference/endpoint/ebay/get-seller-feedback GET /v1/ebay/sellers/{username}/feedback A seller's recent buyer-feedback comments. ## Path Parameters The eBay seller username whose feedback comments you want. ## Query Parameters eBay marketplace domain to resolve the seller on. Examples: `com`, `co.uk`, `de`, `fr` Page number for paginated feedback. Range: `1` - `50`. ## Response Marketplace domain the feedback was fetched from. The seller whose feedback was returned. Array of feedback entries. Feedback rating: `positive`, `neutral`, or `negative` (nullable). Buyer's free-text feedback comment (nullable). Buyer username who left the feedback (nullable). The item the feedback relates to (nullable). Raw date string as shown on eBay (nullable). ISO 8601 feedback date (nullable). Pagination metadata with `current_page`, `per_page`, `total_pages`, `total_results`. ISO 8601 timestamp when the feedback was scraped. ### Example Response ```json theme={null} { "domain": "com", "username": "topgames_us", "feedback": [ { "rating": "positive", "comment": "Fast shipping, item exactly as described. A+++", "rater": "buyer_jane", "item": "Nintendo Switch OLED Model White", "date_raw": "Jun 10, 2026", "date_at": "2026-06-10T00:00:00Z" } ], "pagination": { "current_page": 1, "per_page": 25, "total_pages": 50, "total_results": 1250 }, "scraped_at": "2026-06-21T12:00:00Z" } ``` Each seller-feedback request costs **10 credits**. Failed requests are not charged. # Get Seller Listings Source: https://docs.scrapebadger.com/api-reference/endpoint/ebay/get-seller-items GET /v1/ebay/sellers/{username}/items List the active listings of a single eBay seller. ## Path Parameters The eBay seller username whose storefront listings you want. ## Query Parameters eBay marketplace domain to resolve the seller on. Examples: `com`, `co.uk`, `de`, `fr` Optional keyword filter within the seller's store. Page number for paginated results. Range: `1` - `100`. Results per page. Clamped to one of `60`, `120`, or `240`. ## Response Marketplace domain that was searched. The seller whose listings were returned. Array of the seller's active listings (same `SearchResult` shape as [search](/api-reference/endpoint/ebay/search)). Position on the page (1-based). eBay listing item id. Listing title. Full URL to the listing. Primary image URL. Price object with `value`, `currency`, `symbol`, `raw`. Item condition label. `Buy It Now`, `Auction`, or `Best Offer`. Whether the listing is an auction. Number of bids (auctions only, nullable). Relative time remaining, e.g. `12h 16m` (auctions only, nullable). Current high bid for auction listings with `value`, `currency`, `symbol`, `raw`; mirrors `price`. Null for non-auction (fixed-price) listings. Shipping text. Number of watchers (nullable). Always `null`. eBay renders its "Sponsored" badge into every card as anti-scraping bait, so promoted placements cannot be distinguished from organic results. Pagination metadata with `current_page`, `per_page`, `total_pages`, `total_results`. ISO 8601 timestamp when the results were scraped. ### Example Response ```json theme={null} { "domain": "com", "username": "topgames_us", "results": [ { "position": 1, "item_id": "256123456789", "title": "Nintendo Switch OLED Model White Console - Brand New Sealed", "url": "https://www.ebay.com/itm/256123456789", "image": "https://i.ebayimg.com/images/g/abc/s-l500.jpg", "price": { "value": 299.99, "currency": "USD", "symbol": "$", "raw": "$299.99" }, "condition": "Brand New", "buying_format": "Buy It Now", "is_auction": false, "shipping": "Free shipping", "watchers": 18, "is_sponsored": null } ], "pagination": { "current_page": 1, "per_page": 60, "total_pages": 23, "total_results": 1342 }, "scraped_at": "2026-06-21T12:00:00Z" } ``` Each seller-listings request costs **5 credits**. Failed requests are not charged. # List Categories Source: https://docs.scrapebadger.com/api-reference/endpoint/ebay/list-categories GET /v1/ebay/categories List eBay's top-level category id aliases. Returns the reference list of top-level eBay category aliases and their ids. Use a returned `category_id` with [`/v1/ebay/categories/{category_id}/items`](/api-reference/endpoint/ebay/browse-category) to browse listings, or with the [`category_id`](/api-reference/endpoint/ebay/search) parameter on search. ## Response Array of category aliases. Human-readable category name (e.g. `Electronics`). eBay category id (e.g. `293`). Parent category name, if nested (nullable). ### Example Response ```json theme={null} { "categories": [ { "name": "Electronics", "category_id": "293", "parent": null }, { "name": "Video Games & Consoles", "category_id": "1249", "parent": null }, { "name": "Fashion", "category_id": "11450", "parent": null }, { "name": "Home & Garden", "category_id": "11700", "parent": null } ] } ``` Listing categories is a **free** reference endpoint (0 credits). # List Markets Source: https://docs.scrapebadger.com/api-reference/endpoint/ebay/list-markets GET /v1/ebay/markets List all supported eBay marketplaces with their domains, currencies, locales, and site ids. ## Response Array of supported eBay marketplaces. Market code (e.g. `US`, `GB`, `DE`). eBay domain TLD to use in the `domain` query parameter (e.g. `com`, `co.uk`). ISO 3166-1 alpha-2 country code. ISO 4217 currency code used in this market. BCP-47 locale (e.g. `en-US`). Marketplace country name. eBay legacy global site id. ### Example Response ```json theme={null} { "markets": [ { "code": "US", "domain": "com", "country": "US", "currency": "USD", "locale": "en-US", "name": "United States", "site_id": 0 }, { "code": "GB", "domain": "co.uk", "country": "GB", "currency": "GBP", "locale": "en-GB", "name": "United Kingdom", "site_id": 3 }, { "code": "DE", "domain": "de", "country": "DE", "currency": "EUR", "locale": "de-DE", "name": "Germany", "site_id": 77 }, { "code": "AU", "domain": "com.au", "country": "AU", "currency": "AUD", "locale": "en-AU", "name": "Australia", "site_id": 15 } ] } ``` Listing markets is a **free** reference endpoint (0 credits). # Search Listings Source: https://docs.scrapebadger.com/api-reference/endpoint/ebay/search GET /v1/ebay/search Search an eBay marketplace for active listings. ## Query Parameters Search keywords. Matches against listing titles. eBay marketplace domain TLD or alias. See [`/v1/ebay/markets`](/api-reference/endpoint/ebay/list-markets) for all supported values. Examples: `com`, `co.uk`, `de`, `fr`, `com.au` Restrict results to an eBay category id. Use [`/v1/ebay/categories`](/api-reference/endpoint/ebay/list-categories) to look up ids. Page number for paginated results. Range: `1` - `1000`. Use `pagination.has_more` to know when to stop — eBay re-serves its last page if you ask past the end, so this API returns an empty page there. Results per page. Clamped to one of `60`, `120`, or `240`. Sort order for results. | Value | Description | | - | - | | `best_match` | Best match (default) | | `ending_soonest` | Auctions ending soonest first | | `newly_listed` | Most recently listed | | `price_low_to_high` | Cheapest first (incl. shipping) | | `price_high_to_low` | Most expensive first (incl. shipping) | Item condition filter. | Value | Description | | - | - | | `new` | Brand new | | `open_box` | New (other) / open box | | `refurbished` | Refurbished (any grade) | | `used` | Pre-owned | | `for_parts` | For parts or not working | | `graded` | Trading cards: slabbed (PSA / BGS / CGC) | | `ungraded` | Trading cards: raw | `graded` / `ungraded` are eBay's card-specific conditions. Pricing a raw card against sales that include slabs skews the average badly — price the two separately. Buying format filter. | Value | Description | | - | - | | `auction` | Auction listings | | `buy_it_now` | Fixed-price listings | | `best_offer` | Listings accepting best offers | Minimum price filter in the marketplace's local currency. Maximum price filter in the marketplace's local currency. Only return listings with free shipping. Item location. | Value | Description | | - | - | | `domestic` | Only items located in this marketplace's own country (`domain=fr` → France only) | | `worldwide` | Items from every country | Omit it and you get eBay's default, which mixes foreign listings into a national marketplace. Two things follow, and both matter for price research: a national price series picks up sales that never happened in that country, and a foreign listing's price is shown **converted** into the marketplace's currency rather than the amount it actually sold for. `location=domestic` removes both. ## Response The search query that was executed. Marketplace domain that was searched. The category id filter applied (nullable). Always `false` for active-listing search (see [`/completed`](/api-reference/endpoint/ebay/completed) for sold). Array of matching listings. Position on the page (1-based). eBay listing item id. eBay catalog product id, if part of the catalog (nullable). Listing title. Full URL to the listing. Primary image URL. Price object with `value`, `currency`, `symbol`, `raw`. Strikethrough original price (nullable). Discount percentage off the original price (nullable). Item condition label. Brand name (nullable). `Buy It Now`, `Auction`, or `Best Offer`. Whether the listing is an auction. Number of bids (auctions only, nullable). Relative time remaining for auctions, e.g. `12h 16m` (auctions only, nullable). Current high bid for auction listings with `value`, `currency`, `symbol`, `raw`; mirrors `price`. Null for non-auction (fixed-price) listings. Raw shipping text. Parsed shipping cost (nullable). Whether shipping is free (nullable). Item location text. Returns text (nullable). Number sold (nullable). Sale date text as rendered by eBay, e.g. `2 Jul 2026` (completed/sold cards only; localized on non-English marketplaces, nullable). Best-effort ISO date parsed from `sold_date`, e.g. `2026-07-02` (null when the marketplace's date format is not English). Number of watchers (nullable). Coupon/promo text (nullable). Average catalog rating, if shown (nullable). Total ratings, if shown (nullable). Seller username (nullable). Seller positive-feedback percent (nullable). Seller feedback score (nullable). Program badge, e.g. `eBay Refurbished` (nullable). Always `null`. eBay renders its "Sponsored" badge into every card as anti-scraping bait, so promoted placements cannot be distinguished from organic results. Available filter facets keyed by name, each a list of string values. Pagination metadata with `current_page`, `per_page`, `total_pages`, `total_results`. ISO 8601 timestamp when the results were scraped. ### Example Response ```json theme={null} { "query": "nintendo switch oled", "domain": "com", "category_id": null, "sold": false, "results": [ { "position": 1, "item_id": "256123456789", "product_id": "20057872541", "title": "Nintendo Switch OLED Model White Console - Brand New Sealed", "url": "https://www.ebay.com/itm/256123456789", "image": "https://i.ebayimg.com/images/g/abc/s-l500.jpg", "price": { "value": 299.99, "currency": "USD", "symbol": "$", "raw": "$299.99" }, "original_price": { "value": 349.99, "currency": "USD", "symbol": "$", "raw": "$349.99" }, "discount_percent": 14.0, "condition": "Brand New", "brand": "Nintendo", "buying_format": "Buy It Now", "is_auction": false, "bids": null, "time_left": null, "current_bid": null, "shipping": "Free shipping", "free_shipping": true, "location": "United States", "sold_count": 42, "watchers": 18, "seller_name": "topgames_us", "seller_feedback_percent": 99.4, "seller_feedback_score": 18452, "is_sponsored": null }, { "position": 2, "item_id": "256987654321", "title": "Nintendo Switch OLED Console - No Reserve Auction", "url": "https://www.ebay.com/itm/256987654321", "image": "https://i.ebayimg.com/images/g/def/s-l500.jpg", "price": { "value": 212.5, "currency": "USD", "symbol": "$", "raw": "$212.50" }, "condition": "Used", "buying_format": "Auction", "is_auction": true, "bids": 17, "time_left": "12h 16m", "current_bid": { "value": 212.5, "currency": "USD", "symbol": "$", "raw": "$212.50" }, "shipping": "Free shipping", "free_shipping": true, "location": "United States", "seller_name": "retro_deals", "is_sponsored": null } ], "facets": { "condition": ["New", "Used"], "buying_format": ["Buy It Now", "Auction"] }, "pagination": { "current_page": 1, "per_page": 60, "total_pages": 100, "total_results": 6000 }, "scraped_at": "2026-06-21T12:00:00Z" } ``` Each search request costs **5 credits**. Failed requests are not charged. # Search by Image Source: https://docs.scrapebadger.com/api-reference/endpoint/ebay/search-by-image POST /v1/ebay/search/by-image Search eBay with a photo instead of keywords, using eBay's own visual search. Search active listings **by image**. This is what the camera icon in eBay's own search bar does: the picture is uploaded to eBay, eBay answers with a handle for it, and that handle is searched like a keyword. What comes back is ordinary listings, in exactly the same shape as [`/v1/ebay/search`](/api-reference/endpoint/ebay/search), with `query` set to `null`. Every filter below behaves the way it does there. **Credits:** 10 — twice a keyword search, because each call is two round trips to eBay: one to upload the image, one to fetch the results. ## Body Parameters Send exactly one of `image_url` or `image_base64`. Sending both, or neither, is a `422`. Public http(s) URL of the image to search with. We download it for you. The URL is fetched through the same egress-isolated path that serves the Web Scraping API, so private addresses, cloud metadata endpoints and non-HTTP schemes are refused. The image itself, base64-encoded — use this when the picture is on your own disk and has no public URL. A bare base64 payload and a `data:image/jpeg;base64,...` URL are both accepted, so you can paste one straight out of a browser. JPEG and PNG are verified; the decoded image must be at most **10 MB**. eBay marketplace domain TLD or alias. See [`/v1/ebay/markets`](/api-reference/endpoint/ebay/list-markets) for all supported values. Examples: `com`, `co.uk`, `de`, `fr`, `com.au` Restrict results to an eBay category id. Use [`/v1/ebay/categories`](/api-reference/endpoint/ebay/list-categories) to look up ids. Page number for paginated results. Range: `1` - `1000`. Use `pagination.has_more` to know when to stop. Results per page. Clamped to one of `60`, `120`, or `240`. Item condition filter. | Value | Description | | - | - | | `new` | Brand new | | `open_box` | New (other) / open box | | `refurbished` | Refurbished (any grade) | | `used` | Pre-owned | | `for_parts` | For parts or not working | | `graded` | Trading cards: slabbed (PSA / BGS / CGC) | | `ungraded` | Trading cards: raw | Buying format filter: `auction`, `buy_it_now` or `best_offer`. Minimum price, in the marketplace's own currency. Maximum price, in the marketplace's own currency. Only return listings with free shipping. Item location. `domestic` keeps only items located in that marketplace's own country; `worldwide` widens to every country. Filter by the item's Language aspect: `english`, `japanese`, `chinese` or `korean`. Resolved to each marketplace's own localized aspect name, so one value works on all 18. ## There is no `sort_by` eBay ignores sorting on a visual results page — asking for `price_low_to_high` returns the same first row as best match. Rather than accept a parameter that quietly does nothing, this endpoint does not have one. To order by price, use `min_price` / `max_price` to narrow the band and sort the returned rows yourself. ## Errors A picture eBay cannot read is an error, never an empty result list — so a bad upload is always distinguishable from a genuine no-match. | Status | Meaning | | - | - | | `400` `invalid_image` | The bytes are not a readable image, the image is over 10 MB, `image_url` did not return an image, or the URL was refused. | | `422` | Both `image_url` and `image_base64` were sent, or neither was. | | `422` `blocking_page_detected` | eBay refused the request. Retry. | | `503` `upstream_unavailable` | Our own fetch layer timed out before eBay answered. Retry; you are not charged. | ## Examples ```bash By image URL theme={null} curl -X POST https://scrapebadger.com/v1/ebay/search/by-image \ -H "X-API-Key: $SCRAPEBADGER_API_KEY" \ -H "Content-Type: application/json" \ -d '{"image_url": "https://example.com/sneaker.jpg", "domain": "com"}' ``` ```bash By upload theme={null} curl -X POST https://scrapebadger.com/v1/ebay/search/by-image \ -H "X-API-Key: $SCRAPEBADGER_API_KEY" \ -H "Content-Type: application/json" \ -d "{\"image_base64\": \"$(base64 -w0 sneaker.jpg)\", \"domain\": \"com\"}" ``` ```python Python theme={null} from scrapebadger import ScrapeBadger async with ScrapeBadger(api_key="YOUR_KEY") as client: results = await client.ebay.search.search_by_image( image_url="https://example.com/sneaker.jpg", domain="com", ) for item in results.results: print(item.title, item.price.value, item.price.currency) ``` ```typescript Node theme={null} import { ScrapeBadger } from 'scrapebadger' const client = new ScrapeBadger({ apiKey: 'YOUR_KEY' }) const results = await client.ebay.search.searchByImage({ imageUrl: 'https://example.com/sneaker.jpg', domain: 'com', }) ``` ```bash CLI theme={null} scrapebadger ebay search-by-image --image ./sneaker.jpg --domain com ``` ## Response Identical to [`/v1/ebay/search`](/api-reference/endpoint/ebay/search): `results`, `facets`, `pagination`, `domain` and the scrape timestamps. `query` is `null`, since the search was made from a picture rather than words. # Ad Library Pages Source: https://docs.scrapebadger.com/api-reference/endpoint/facebook/ad-pages GET https://scrapebadger.com/v1/facebook/ads/pages/search Find advertiser Pages in Facebook's Ad Library and pull their transparency profile — likes, verification, Instagram handle, admin locations, page history and political ad spend. Search for **advertiser Pages** in Facebook's Ad Library (the same typeahead the Library UI uses), then pull a Page's full **transparency profile** — ownership, admin country breakdown, creation/rename history, related Pages and, for political/issue advertisers, ad spend. | Endpoint | Returns | | - | - | | `GET /v1/facebook/ads/pages/search` | advertiser Page typeahead search | | `GET /v1/facebook/ads/pages/{page_id}` | one Page's info, transparency and ad spend | **Credits:** 5 (each) ## Authorization Your ScrapeBadger API key. ## Query Parameters — `/ads/pages/search` Advertiser name to search for. ISO 3166-1 alpha-2 country code. The Ad Library is partitioned by country. ## Path Parameters — `/ads/pages/{page_id}` The numeric Page id, as returned in `page_id` on any search result. ISO 3166-1 alpha-2 country code. ## Response — `/ads/pages/search` Each result includes `page_id`, `name`, `page_alias`, `category`, `likes`, `verification` (e.g. `BLUE_VERIFIED`), `entity_type` (e.g. `PERSON_PROFILE`), `country`, `ig_username`, `ig_followers`, `ig_verification`, `image_uri` and `page_is_deleted`. Related search keywords the Ad Library suggests for the query. Number of pages returned. Echoes the query. ## Response — `/ads/pages/{page_id}` Numeric Page id. Page display name. Vanity handle (e.g. `nike`). Facebook Page category. Ad Library entity type. Page like count. Verification badge, e.g. `BLUE_VERIFIED`. Profile photo URL. The Page's about blurb. Whether the Page has been deleted. Whether the Page has ads hidden from the Library. Linked Instagram username. Instagram follower count. Whether the Instagram account is verified. Page creation time, Unix seconds. Page creation time, ISO 8601. Confirmed Page owner: `id`, `name`, `phone_number` and `address` (`city`, `state`, `postal_code`, `country`). Where the Page's admins are located — `{country, country_id, count}` per country. Page transparency history — `{item_type, event_time_utc, event_at}` where `item_type` is `CREATION` or `NAME_CHANGE`. State-controlled-media label, if Facebook applies one. Pages the Library links to this one — `{page_id, page_name, country, country_name, category_name, page_verification, profile_image_uri}`. Political/issue ad spend: `current_week`, `lifetime_by_disclaimer[]` and `weekly_by_disclaimer[]`. Populated only for political/issue advertisers — commercial advertisers return empty spend. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/facebook/ads/pages/search?query=Nike&country=US" \ -H "X-API-Key: YOUR_API_KEY" curl "https://scrapebadger.com/v1/facebook/ads/pages/15087023444?country=US" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/facebook/ads/pages/15087023444?country=US", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const page = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/facebook/ads/pages/15087023444", headers={"X-API-Key": "YOUR_API_KEY"}, params={"country": "US"}, ) page = res.json() ``` ```json Response theme={null} { "page_id": "15087023444", "page_name": "Nike", "page_alias": "nike", "page_category": "Sportswear Store", "entity_type": "BUSINESS", "likes": 39571076, "verification": "BLUE_VERIFIED", "profile_photo": "https://scontent.xx.fbcdn.net/v/t39.30808-1/nike_profile.jpg", "about": "Just Do It.", "page_is_deleted": false, "hidden_ads": false, "ig_username": "nike", "ig_followers": 302514886, "ig_verification": true, "page_creation_utc": 1211328000.0, "page_created_at": "2008-05-21T00:00:00Z", "owner": { "id": "115941125123456", "name": "NIKE, Inc.", "phone_number": "+1 503-671-6453", "address": { "city": "Beaverton", "state": "OR", "postal_code": "97005", "country": "US" } }, "admin_country_counts": [ { "country": "United States", "country_id": "US", "count": 105 }, { "country": "India", "country_id": "IN", "count": 31 } ], "history": [ { "item_type": "CREATION", "event_time_utc": 1211328000.0, "event_at": "2008-05-21T00:00:00Z" }, { "item_type": "NAME_CHANGE", "event_time_utc": 1367539200.0, "event_at": "2013-05-03T00:00:00Z" } ], "state_media_country_label": null, "related_pages": [ { "page_id": "24714361749", "page_name": "Nike Football", "country": "US", "country_name": "United States", "category_name": "Sportswear Store", "page_verification": "BLUE_VERIFIED", "profile_image_uri": "https://scontent.xx.fbcdn.net/v/t39.30808-1/nike_football.jpg" } ], "ad_spend": { "current_week": null, "lifetime_by_disclaimer": [], "weekly_by_disclaimer": [] } } ``` `ad_spend` is populated only for political and issue advertisers — Facebook publishes spend for those, but not for commercial Pages like Nike, which return empty spend. Pair `/ads/pages/search` with [`/ads/search`](/api-reference/endpoint/facebook/ads-search) to go from an advertiser name to their full creative inventory. # Ad Library Search & Get Ad Source: https://docs.scrapebadger.com/api-reference/endpoint/facebook/ads-search GET https://scrapebadger.com/v1/facebook/ads/search Search Facebook's public Ad Library by advertiser or keyword — creative copy, snapshot URL, flight dates, platforms, media and CTA. Search Facebook's public **Ad Library**, the transparency archive of ads running across Facebook, Instagram, Messenger and the Audience Network — or look one up directly by its archive id. | Endpoint | Returns | | - | - | | `GET /v1/facebook/ads/search` | keyword / advertiser search, cursor-paginated | | `GET /v1/facebook/ads/{ad_archive_id}` | one ad by its archive id | **Credits:** 5 (each) ## Authorization Your ScrapeBadger API key. ## Query Parameters — `/ads/search` Advertiser name or keyword. ISO 3166-1 alpha-2 country code. The Ad Library is partitioned by country — the same advertiser returns different ads per market. One of `all`, `political_and_issue_ads`. Political and issue ads carry extra disclaimers in the archive. One of `active`, `inactive`, `all`. Pagination cursor — the `end_cursor` from a previous response. ## Path Parameters — `/ads/{ad_archive_id}` The Ad Library archive id, as returned in `ad_archive_id` on any search result. ISO 3166-1 alpha-2 country code for the lookup. Pass an EU/UK code (e.g. `DE`, `FR`, `GB`) to get the `transparency` object with EU DSA reach and demographic data. ## Response Each `AdLibraryAd` includes `ad_archive_id`, `page_id`, `page_name`, `ad_creative_body`, `ad_creative_link_title`, `ad_creative_link_caption`, `ad_creative_link_description`, `ad_snapshot_url` (Facebook-hosted rendered preview), `start_date_utc`, `start_date`, `end_date_utc`, `end_date` (`null` while the ad is still running), `is_active`, `publisher_platforms[]` (`FACEBOOK`, `INSTAGRAM`, `MESSENGER`, `AUDIENCE_NETWORK`), `images[]`, `videos[]`, `cta_text` (button label) and `cta_type` (Facebook's CTA enum, e.g. `SHOP_NOW`, `LEARN_MORE`, `SIGN_UP`). Lookup endpoint only, when `country` is an EU/UK market or the ad targets the EU. Carries `payer_beneficiary[]` (`{payer, beneficiary}` pairs), `targets_eu`, `has_violating_payer_beneficiary`, `is_ad_taken_down`, `is_violating_eu_siep` and `eu_transparency` — the DSA disclosure: `eu_total_reach`, `gender_audience`, `age_audience_min` / `age_audience_max`, `location_audience[]` (`{name, type, excluded, num_obfuscated}`) and `age_country_gender_reach_breakdown[]` (per-country `age_gender_breakdowns[]` with `age_range`, `male`, `female`, `unknown` reach). Number of ads in this page. Pass as `after` for the next page. Search only. Whether more ads are reachable. Search only. Echoes the query (or the archive id on the lookup endpoint). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/facebook/ads/search?query=Nike&country=US&active_status=active" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/facebook/ads/search?" + new URLSearchParams({ query: "Nike", country: "US", active_status: "active", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/facebook/ads/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "Nike", "country": "US", "active_status": "active"}, ) data = res.json() ``` ```json Response theme={null} { "ads": [ { "ad_archive_id": "1284772093418206", "page_id": "15087023444", "page_name": "Nike", "ad_creative_body": "Built for the long run. The new Pegasus 42 lands today.", "ad_creative_link_title": "Pegasus 42", "ad_creative_link_caption": "nike.com", "ad_creative_link_description": "Free shipping for members.", "ad_snapshot_url": "https://www.facebook.com/ads/library/?id=1284772093418206", "start_date_utc": 1785225600.0, "start_date": "2026-07-26T14:40:00Z", "end_date_utc": null, "end_date": null, "is_active": true, "publisher_platforms": ["FACEBOOK", "INSTAGRAM"], "images": [ "https://scontent.xx.fbcdn.net/v/t39.35426-6/449120_n.jpg" ], "videos": [], "cta_text": "Shop Now", "cta_type": "SHOP_NOW" } ], "count": 1, "end_cursor": "AQHZHZHNfbGlicmFyeV9jdXJzb3JfMDAx", "has_next_page": true, "query": "Nike" } ``` ## Example — EU transparency Look an ad up with an EU `country` to get the DSA `transparency` block: ```bash cURL theme={null} curl "https://scrapebadger.com/v1/facebook/ads/1284772093418206?country=DE" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response (transparency excerpt) theme={null} { "ads": [ { "ad_archive_id": "1284772093418206", "page_name": "Nike", "transparency": { "payer_beneficiary": [ { "payer": "Nike Retail B.V.", "beneficiary": "Nike Retail B.V." } ], "targets_eu": true, "has_violating_payer_beneficiary": false, "is_ad_taken_down": false, "is_violating_eu_siep": false, "eu_transparency": { "targets_eu": true, "eu_total_reach": 1834920, "gender_audience": "All", "age_audience_min": 18, "age_audience_max": 65, "location_audience": [ { "name": "Germany", "type": "country", "excluded": false, "num_obfuscated": 0 } ], "age_country_gender_reach_breakdown": [ { "country": "DE", "age_gender_breakdowns": [ { "age_range": "18-24", "male": 141203, "female": 152884, "unknown": 4102 }, { "age_range": "25-34", "male": 289441, "female": 301276, "unknown": 8817 } ] } ] } } } ], "count": 1, "query": "1284772093418206" } ``` The Ad Library is country-partitioned. To size a competitor's full spend footprint, sweep `country` across the markets you care about rather than paginating a single one deeper. On the lookup endpoint, an EU `country` additionally unlocks the DSA `transparency` block — reach, demographics and payer/beneficiary — even for ads you first found via a `US` search. # Get Group & Group Posts Source: https://docs.scrapebadger.com/api-reference/endpoint/facebook/get-group GET https://scrapebadger.com/v1/facebook/groups/{group_id} Facebook Group metadata — privacy, member count, description, creation date — plus the group feed. Fetch a Facebook Group's metadata, and its feed from the companion endpoint. | Endpoint | Returns | | - | - | | `GET /v1/facebook/groups/{group_id}` | `Group` metadata | | `GET /v1/facebook/groups/{group_id}/posts` | the group feed (`Post[]`) | **Credits:** 5 (each) ## Authorization Your ScrapeBadger API key. ## Path Parameters Numeric group id or the group's vanity slug — the `facebook.com/groups/` segment. ## Query Parameters `/posts` only. Pagination cursor — the `end_cursor` from a previous response. ## Response — `/groups/{group_id}` Returns a single `Group` object. Numeric group id. Group name. Canonical `facebook.com/groups/` URL. Facebook's privacy setting — typically `Public` or `Private`. Whether the group is listed in search (`visible`) or hidden. Number of members. Group intro / rules text. Cover image URL. Group creation time, Unix seconds. Group creation time, ISO 8601 UTC. ## Response — `/groups/{group_id}/posts` Full `Post` objects — `id`, `post_id`, `url`, `permalink_url`, `message`, `creation_time_utc`, `created_at`, `author` (Actor), `attachments[]` (Media), `reaction_count`, `reaction_count_text`, `top_reactions[]`, `comment_count`, `share_count`, `story_type`. See [Get Page or Profile Posts](/api-reference/endpoint/facebook/get-page-posts) for the field-by-field breakdown. Number of posts in this page. Pass as `after` for the next page. Whether more posts are reachable. A **private** group returns metadata but an empty `posts[]` — Facebook serves no feed units to a non-member session. Check `privacy` before treating an empty feed as an error. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/facebook/groups/1503289913" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/facebook/groups/1503289913", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const group = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/facebook/groups/1503289913", headers={"X-API-Key": "YOUR_API_KEY"}, ) group = res.json() ``` ```json Response theme={null} { "id": "1503289913", "name": "Brooklyn Buy Nothing", "url": "https://www.facebook.com/groups/1503289913", "privacy": "Public", "visibility": "visible", "member_count": 42817, "description": "Give and receive freely with your Brooklyn neighbours. No selling, no trading, no cash.", "cover_photo": "https://scontent.xx.fbcdn.net/v/t39.30808-6/771204_n.jpg", "creation_time_utc": 1476403200.0, "created_at": "2016-10-14T00:00:00Z" } ``` Discover groups with [`/search/groups`](/api-reference/endpoint/facebook/search) — it returns `SearchResult` objects with `type: "group"`; take the `id` here for full metadata. # Get Page or Profile Source: https://docs.scrapebadger.com/api-reference/endpoint/facebook/get-page GET https://scrapebadger.com/v1/facebook/pages/{identifier} A Facebook Page or public profile — category, verification, follower and like counts, and the About tile (website, phone, email, address, rating). Fetch a Facebook Page or public profile by vanity slug or numeric id. Both endpoints share one `Profile` model; the `type` field distinguishes them. | Endpoint | Use for | | - | - | | `GET /v1/facebook/pages/{identifier}` | business / organization Pages | | `GET /v1/facebook/profiles/{identifier}` | personal and public profiles | Both fetch the **About** tile as a second hop, so `website`, `phone`, `email`, `address` and `rating` are populated where the entity publishes them. **Credits:** 5 (each) ## Authorization Your ScrapeBadger API key. ## Path Parameters Vanity slug (the `facebook.com/` segment, e.g. `nasa`) or the numeric entity id. ## Response Returns a single `Profile` object. Numeric entity id. Display name. Canonical facebook.com URL. Vanity slug, when the entity has one. `profile` or `page`. Blue-check verification. Avatar URL. Cover image URL. Page category, e.g. `Government Organization`. Bio / Page intro. Follower count. `null` when Facebook renders only an abbreviated string or the entity hides it. Page like count. Friend count (profiles). Whether the entity is a business Page. Website from the About tile. Public phone number. Public email address. Public street address. Average rating, `0`–`5`. Number of ratings. Remaining raw About-tile key/values that have no first-class field — hours, price range, founding date, mission, awards and other Page-type-specific entries. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/facebook/pages/nasa" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch("https://scrapebadger.com/v1/facebook/pages/nasa", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY }, }); const page = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/facebook/pages/nasa", headers={"X-API-Key": "YOUR_API_KEY"}, ) page = res.json() ``` ```json Response theme={null} { "id": "54971236771", "name": "NASA", "url": "https://www.facebook.com/NASA", "username": "NASA", "type": "page", "is_verified": true, "profile_picture": "https://scontent.xx.fbcdn.net/v/t39.30808-1/32118_n.jpg", "cover_photo": "https://scontent.xx.fbcdn.net/v/t39.30808-6/91224_n.jpg", "category": "Government Organization", "description": "Explore the universe and discover our home planet with NASA.", "followers_count": 22140883, "likes_count": 21876204, "friends_count": null, "is_business_page": true, "website": "http://www.nasa.gov", "phone": null, "email": null, "address": "300 E Street SW, Washington, DC 20546", "rating": null, "rating_count": null, "about": { "mission": "To explore the secrets of the universe for the benefit of all.", "founded": "July 29, 1958" } } ``` Personal profiles expose far less than Pages: most fields on a locked-down profile come back `null`. `404` means the slug or id does not resolve, or the entity is region-restricted. # Get Page or Profile Posts Source: https://docs.scrapebadger.com/api-reference/endpoint/facebook/get-page-posts GET https://scrapebadger.com/v1/facebook/pages/{identifier}/posts A Facebook Page or profile timeline — posts with attachments, reaction breakdown, comment and share counts, cursor-paginated. Fetch the timeline of a Page or profile. Both endpoints return the same post feed envelope and paginate with the same Relay cursor. Facebook decides the page size and currently serves about **3 posts per page** to a logged-out client, regardless of how many are asked for. To collect a date range, follow `end_cursor` while `has_next_page` is true and stop when `created_at` passes your cut-off — the feed is returned newest-first. | Endpoint | Use for | | - | - | | `GET /v1/facebook/pages/{identifier}/posts` | Page timelines | | `GET /v1/facebook/profiles/{identifier}/posts` | profile timelines | **Credits:** 5 (each) ## Authorization Your ScrapeBadger API key. ## Path Parameters Vanity slug (e.g. `nasa`) or the numeric entity id. ## Query Parameters Pagination cursor — the `end_cursor` from a previous response. ## Response Each `Post` includes `id`, `post_id`, `url`, `permalink_url`, `message`, `story_type`, `creation_time_utc`, `created_at`, `author` (Actor — `id`, `name`, `url`, `profile_picture`, `is_verified`, `typename`), `attachments[]` (Media — `type` (`Photo` · `Video`), `id`, `uri`, `width`, `height`, `url`, `playable_url`), `reaction_count`, `reaction_count_text`, `top_reactions[]` (`{ name, count }`), `comment_count` and `share_count`. Number of posts in this page. Pass as `after` for the next page. Whether more posts are reachable. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/facebook/pages/nasa/posts" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/facebook/pages/nasa/posts", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/facebook/pages/nasa/posts", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "posts": [ { "id": "pfbid02Kx9YqLmN4vT7wJ3hR8sQ2fZ1nB6cD5", "post_id": "1094832771620487", "url": "https://www.facebook.com/NASA/posts/pfbid02Kx9YqLmN4vT7wJ3hR8sQ2fZ1nB6cD5", "permalink_url": "https://www.facebook.com/NASA/posts/pfbid02Kx9YqLmN4vT7wJ3hR8sQ2fZ1nB6cD5", "message": "Webb just resolved the disk around a star 1,300 light-years away. Those rings? Planets, forming right now.", "creation_time_utc": 1785398400.0, "created_at": "2026-07-28T14:40:00Z", "author": { "id": "54971236771", "name": "NASA", "url": "https://www.facebook.com/NASA", "profile_picture": "https://scontent.xx.fbcdn.net/v/t39.30808-1/32118_n.jpg", "is_verified": true, "typename": "Page" }, "attachments": [ { "type": "Photo", "id": "1094832768287154", "uri": "https://scontent.xx.fbcdn.net/v/t39.30808-6/558921_n.jpg", "width": 2048, "height": 2048, "url": "https://www.facebook.com/photo/?fbid=1094832768287154", "playable_url": null } ], "reaction_count": 48213, "reaction_count_text": "48K", "top_reactions": [ { "name": "like", "count": 31204 }, { "name": "love", "count": 14882 }, { "name": "wow", "count": 2127 } ], "comment_count": 1844, "share_count": 6721, "story_type": null } ], "count": 1, "end_cursor": "AQHUaW1lbGluZV9jdXJzb3JfMDAx", "has_next_page": true } ``` Personal profiles that Facebook shows only to signed-in visitors return **503** with a message saying so, not an empty `posts[]`. An empty `posts[]` with `has_next_page: false` means the end of the feed. # Get Post Source: https://docs.scrapebadger.com/api-reference/endpoint/facebook/get-post GET https://scrapebadger.com/v1/facebook/posts/{post_id} A single Facebook post by numeric id, pfbid, permalink.php form or reel URL — with attachments, reaction breakdown, share and comment counts. Fetch one post. Facebook post ids come in several shapes — bare numeric ids, `pfbid` strings, `permalink.php` query forms and `reel/` URLs. When you have a full URL, pass it as `url`; it overrides the path id. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Post id — numeric or `pfbid`. Ignored when `url` is supplied, but still required as a path segment (pass any placeholder, e.g. `0`). ## Query Parameters Full post permalink or reel URL. **Overrides `post_id`.** Use this for `permalink.php?story_fbid=…&id=…` and `{page}/posts/{pfbid}` forms that a bare id cannot resolve. ## Response Returns a single `Post` object. Story id. Post id. Canonical post URL. Permalink URL. Post text. Facebook's story classification, e.g. a shared-link or life-event story. Post time, Unix seconds. Post time, ISO 8601 UTC. `id`, `name`, `url`, `profile_picture`, `is_verified`, `typename`. `type` (`Photo` · `Video`), `id`, `uri`, `width`, `height`, `url`, `playable_url`. Total reactions. Facebook's abbreviated display string, e.g. `48K`. `{ name, count }` — `like`, `love`, `haha`, `wow`, `sad`, `angry`, `care`. Number of comments. Number of shares. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/facebook/posts/0?url=https://www.facebook.com/NASA/posts/pfbid02Kx9YqLmN4vT7wJ3hR8sQ2fZ1nB6cD5" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/facebook/posts/1094832771620487", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const post = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/facebook/posts/1094832771620487", headers={"X-API-Key": "YOUR_API_KEY"}, ) post = res.json() ``` ```json Response theme={null} { "id": "pfbid02Kx9YqLmN4vT7wJ3hR8sQ2fZ1nB6cD5", "post_id": "1094832771620487", "url": "https://www.facebook.com/NASA/posts/pfbid02Kx9YqLmN4vT7wJ3hR8sQ2fZ1nB6cD5", "permalink_url": "https://www.facebook.com/NASA/posts/pfbid02Kx9YqLmN4vT7wJ3hR8sQ2fZ1nB6cD5", "message": "Webb just resolved the disk around a star 1,300 light-years away. Those rings? Planets, forming right now.", "creation_time_utc": 1785398400.0, "created_at": "2026-07-28T14:40:00Z", "author": { "id": "54971236771", "name": "NASA", "url": "https://www.facebook.com/NASA", "profile_picture": "https://scontent.xx.fbcdn.net/v/t39.30808-1/32118_n.jpg", "is_verified": true, "typename": "Page" }, "attachments": [ { "type": "Photo", "id": "1094832768287154", "uri": "https://scontent.xx.fbcdn.net/v/t39.30808-6/558921_n.jpg", "width": 2048, "height": 2048, "url": "https://www.facebook.com/photo/?fbid=1094832768287154", "playable_url": null } ], "reaction_count": 48213, "reaction_count_text": "48K", "top_reactions": [ { "name": "like", "count": 31204 }, { "name": "love", "count": 14882 }, { "name": "wow", "count": 2127 } ], "comment_count": 1844, "share_count": 6721, "story_type": null } ``` A deleted or region-restricted post returns `404`. Comments are a separate, heavier call — [`/posts/{post_id}/comments`](/api-reference/endpoint/facebook/get-post-comments). # Get Post Comments Source: https://docs.scrapebadger.com/api-reference/endpoint/facebook/get-post-comments GET https://scrapebadger.com/v1/facebook/posts/{post_id}/comments The comment thread on a Facebook post — author, message, reactions and reply counts, cursor-paginated. Fetch the comment thread on a post. Every page — the first included — replays Facebook's own comment-list GraphQL query, which is why this endpoint costs double. Facebook serves **10 comments per page**; follow `end_cursor` while `has_next_page` is true to walk the whole thread. **Credits:** 10 ## Authorization Your ScrapeBadger API key. ## Path Parameters Post id — numeric or `pfbid`. Ignored when `url` is supplied, but still required as a path segment (pass any placeholder, e.g. `0`). ## Query Parameters Full post permalink or reel URL. **Overrides `post_id`.** Pagination cursor — the `end_cursor` from a previous response. One of `relevance` (Facebook's ranked order), `newest` (reverse chronological), or `most_relevant` (an alias of `relevance`). The sort applies from the first page on, so do not mix orders across a single traversal — the cursors are not interchangeable. ## Response Each `Comment` includes `id`, `message`, `author` (Actor — `id`, `name`, `url`, `profile_picture`, `is_verified`, `typename`), `creation_time_utc`, `created_at`, `reaction_count` and `reply_count`. Number of comments in this page. Facebook's own reported comment total for the post. It can exceed the number of comments actually reachable through pagination. Pass as `after` for the next page. Whether more comments are reachable. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/facebook/posts/1094832771620487/comments?sort=newest" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/facebook/posts/1094832771620487/comments?" + new URLSearchParams({ sort: "newest" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/facebook/posts/1094832771620487/comments", headers={"X-API-Key": "YOUR_API_KEY"}, params={"sort": "newest"}, ) data = res.json() ``` ```json Response theme={null} { "comments": [ { "id": "Y29tbWVudDoxMDk0ODMyNzcxNjIwNDg3XzQ0MjE5", "message": "The resolution on this is unreal. What filter set was used?", "author": { "id": "100001874420913", "name": "Priya Raman", "url": "https://www.facebook.com/profile.php?id=100001874420913", "profile_picture": "https://scontent.xx.fbcdn.net/v/t1.30497-1/22841_n.jpg", "is_verified": false, "typename": "User" }, "creation_time_utc": 1785399720.0, "created_at": "2026-07-28T15:02:00Z", "reaction_count": 412, "reply_count": 7 }, { "id": "Y29tbWVudDoxMDk0ODMyNzcxNjIwNDg3XzQ0MjIx", "message": "Planets forming in real time. What a era to be alive.", "author": { "id": "100009338271604", "name": "Tomás Lindqvist", "url": "https://www.facebook.com/profile.php?id=100009338271604", "profile_picture": "https://scontent.xx.fbcdn.net/v/t1.30497-1/91038_n.jpg", "is_verified": false, "typename": "User" }, "creation_time_utc": 1785400380.0, "created_at": "2026-07-28T15:13:00Z", "reaction_count": 88, "reply_count": 0 } ], "count": 2, "total_count": 1844, "end_cursor": "AQHNvbW1lbnRzX2N1cnNvcl8wMDE=", "has_next_page": true } ``` `total_count` is what Facebook advertises, not what it will serve. Treat `has_next_page: false` as the real end of the thread — deep comment traversal is silently capped. # Marketplace Category & Reference Source: https://docs.scrapebadger.com/api-reference/endpoint/facebook/marketplace-category GET https://scrapebadger.com/v1/facebook/marketplace/category/{category} Browse a whole Facebook Marketplace category in one location, plus the free location and category slug catalogs. Browse a Marketplace category feed — `vehicles`, `propertyrentals`, `electronics`, `apparel` and the rest — scoped to one location, with price and sort filters. Returns the same `MarketplaceListing` shape as [`/marketplace/search`](/api-reference/endpoint/facebook/marketplace-search). This page also documents the two free reference endpoints that list the valid `location` and `category` slugs. **Credits:** 5 (category browse) · 0 (`/marketplace/locations`, `/marketplace/categories`) ## Authorization Your ScrapeBadger API key. ## Path Parameters Marketplace category slug — one of `vehicles`, `propertyrentals`, `propertyforsale`, `apparel`, `electronics`, `entertainment`, `family`, `free`, `garden`, `hobbies`, `homegoods`, `homeimprovement`, `instruments`, `officesupplies`, `petsupplies`, `sportinggoods`, `toys`. ## Query Parameters A Facebook Marketplace **location slug** (`nyc`, `la`, `london`) or a numeric Facebook place id. Human-readable names such as `Durham, UK` return a `400 invalid_location` rather than silently browsing a different place — see [Location targeting](/api-reference/endpoint/facebook/marketplace-search#location-targeting). Facebook honours `radius` on search only, so there is no `radius` here. Minimum price. Maximum price. One of `best_match`, `price_ascend`, `price_descend`, `distance_ascend`, `creation_time_descend`. Pagination cursor — the `end_cursor` from a previous response. ## Response Same shape as [`/marketplace/search`](/api-reference/endpoint/facebook/marketplace-search) — `id`, `title`, `url`, `price_formatted`, `price_amount`, `currency`, `primary_photo`, `creation_time_utc`, `created_at`, `location_text`, `city_page_id`, `city`, `state`, `latitude`, `longitude`, `subtitles[]`, `delivery_types[]`, `attributes`, `is_sold`, `is_pending`, `is_live` and `seller`. Number of listings in this page. Pass as `after` for the next page. Whether more listings are reachable. Echoes the category slug that was browsed. The location value you sent. The location Facebook actually browsed: `slug`, `latitude`, `longitude` and `radius`. Verify it against your target geography before ingesting. Vertical categories fill `attributes` with vertical-specific keys — vehicle `make` / `model` / `mileage` on `vehicles`, `beds` / `baths` on `propertyrentals` and `propertyforsale`. `subtitles[]` carries the same metadata as Facebook's own display bullets. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/facebook/marketplace/category/vehicles?location=la&max_price=15000&sort_by=price_ascend" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/facebook/marketplace/category/vehicles?" + new URLSearchParams({ location: "la", max_price: "15000", sort_by: "price_ascend", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/facebook/marketplace/category/vehicles", headers={"X-API-Key": "YOUR_API_KEY"}, params={"location": "la", "max_price": 15000, "sort_by": "price_ascend"}, ) data = res.json() ``` ```json Response theme={null} { "listings": [ { "id": "992418377620134", "title": "2014 Honda Civic LX", "url": "https://www.facebook.com/marketplace/item/992418377620134/", "price_formatted": "$8,900", "price_amount": "8900", "currency": "USD", "primary_photo": "https://scontent.xx.fbcdn.net/v/t45.5328-4/553219_n.jpg", "photos": [], "creation_time_utc": 1785044100.0, "created_at": "2026-07-24T12:15:00Z", "location_text": "Pasadena, CA", "city": "Pasadena", "state": "CA", "latitude": 34.1478, "longitude": -118.1445, "category_id": "vehicles", "subtitles": ["112,400 miles"], "delivery_types": ["local_pick_up"], "attributes": { "make": "Honda", "model": "Civic", "mileage": "112400" }, "is_sold": false, "is_pending": false, "is_live": true, "seller": { "id": "100002218844907", "name": "Marisol Vega", "url": "https://www.facebook.com/profile.php?id=100002218844907", "profile_picture": "https://scontent.xx.fbcdn.net/v/t1.30497-1/33119_n.jpg", "typename": "User" } } ], "count": 1, "end_cursor": "AQHVjZWhpY2xlc19jdXJzb3JfMDAx", "has_next_page": true, "query": "vehicles", "location": "la" } ``` ## Reference endpoints Both are free (0 credits) and hit no Facebook surface. ### `GET /v1/facebook/marketplace/locations` `{ slug, name }` pairs for the high-traffic Marketplace cities — `nyc`, `la`, `chicago`, `houston`, `seattle`, `sanfrancisco`, `miami`, `atlanta`, `london`, `toronto`, `sydney`. Not exhaustive: any city slug Facebook accepts works as a `location`. Number of locations returned. ### `GET /v1/facebook/marketplace/categories` `{ slug, name }` pairs for every Marketplace top-level category. Number of categories returned. ```bash cURL theme={null} curl "https://scrapebadger.com/v1/facebook/marketplace/categories" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} { "categories": [ { "slug": "vehicles", "name": "Vehicles" }, { "slug": "propertyrentals", "name": "Property Rentals" }, { "slug": "electronics", "name": "Electronics" } ], "count": 17 } ``` # Get Marketplace Item Source: https://docs.scrapebadger.com/api-reference/endpoint/facebook/marketplace-item GET https://scrapebadger.com/v1/facebook/marketplace/item/{item_id} Full Facebook Marketplace listing detail — description body, complete photo gallery, vertical attributes and the seller profile. Fetch one Marketplace listing in full. Unlike the truncated feed cards returned by search and category browse, this endpoint populates the `description` body, the complete `photos[]` gallery and the vertical-specific `attributes` map. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Marketplace listing id — the numeric segment of `facebook.com/marketplace/item//`, and the `id` field on every search or category result. ## Response Returns a single `MarketplaceListing` object (not wrapped in an envelope). Marketplace listing id. Listing title. Seller-authored display title, when Facebook renders a different one. Canonical listing permalink. Localized display price, e.g. `$1,150`. Numeric price as a string. Facebook's minor-unit representation of the price. Previous price, when the listing is discounted. Lower bound for range listings (e.g. rentals). Upper bound for range listings. ISO currency code. Cover image URL. Full gallery of image URLs. Listing creation time, Unix seconds. Listing creation time, ISO 8601 UTC. Display location string, e.g. `Whitley Bay, Tyne and Wear`. City. Populated on feed cards only — `null` here; read `location_text`. State / region. Populated on feed cards only — `null` here; read `location_text`. Canonical Facebook place id for the listing's city. Pass it back as a `location` on [`/marketplace/search`](/api-reference/endpoint/facebook/marketplace-search) to search that town directly. Approximate latitude, straight from Facebook's own listing data — never geocoded by us. Facebook coarsens it to the seller's area, not the address. Approximate longitude, same source and precision as `latitude`. Marketplace category the listing sits in. Facebook's own metadata bullets — condition, mileage, beds/baths. `local_pick_up` and/or `shipping`. Vertical-specific key/values — vehicle `make`/`model`/`mileage`, property `beds`/`baths`. Listing has sold. Sold listings stay retrievable. Sale pending. Listing is currently live. Listing is hidden from browse. `id`, `name`, `url`, `profile_picture`, `is_verified`, `typename`. Full listing body. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/facebook/marketplace/item/1284419203847561" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/facebook/marketplace/item/1284419203847561", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const listing = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/facebook/marketplace/item/1284419203847561", headers={"X-API-Key": "YOUR_API_KEY"}, ) listing = res.json() ``` ```json Response theme={null} { "id": "1284419203847561", "title": "MacBook Pro 14\" M3 Pro 18GB/512GB", "custom_title": null, "url": "https://www.facebook.com/marketplace/item/1284419203847561/", "price_formatted": "$1,150", "price_amount": "1150", "amount_with_offset": "115000", "strikethrough_price": "$1,399", "min_price": null, "max_price": null, "currency": "USD", "primary_photo": "https://scontent.xx.fbcdn.net/v/t45.5328-4/478213_n.jpg", "photos": [ "https://scontent.xx.fbcdn.net/v/t45.5328-4/478213_n.jpg", "https://scontent.xx.fbcdn.net/v/t45.5328-4/478214_n.jpg", "https://scontent.xx.fbcdn.net/v/t45.5328-4/478215_n.jpg" ], "creation_time_utc": 1785312840.0, "created_at": "2026-07-27T14:54:00Z", "location_text": "Brooklyn, NY", "city": null, "state": null, "city_page_id": "108424145849621", "latitude": 40.6782, "longitude": -73.9442, "category_id": "electronics", "subtitles": ["Used - Like New"], "delivery_types": ["local_pick_up", "shipping"], "attributes": { "condition": "used_like_new" }, "is_sold": false, "is_pending": false, "is_live": true, "is_hidden": false, "seller": { "id": "100004421887301", "name": "Daniel Ortiz", "url": "https://www.facebook.com/profile.php?id=100004421887301", "profile_picture": "https://scontent.xx.fbcdn.net/v/t1.30497-1/84628_n.jpg", "is_verified": false, "typename": "User" }, "description": "Selling my 14\" MacBook Pro (M3 Pro, 18GB RAM, 512GB SSD). AppleCare until March 2027, 61 battery cycles, no scratches. Comes with the original box and 96W charger. Cash or Zelle, pickup in Park Slope." } ``` `latitude`/`longitude` are the strongest listing-level location evidence and come from Facebook, not from any geocoding of ours. If Facebook omits them for a listing, `location_text` and `city_page_id` remain authoritative for that listing's place. A listing that has been deleted or is region-restricted returns `404`. Sold listings remain retrievable with `is_sold: true` — use that instead of treating disappearance as a sale signal. # Marketplace Search Source: https://docs.scrapebadger.com/api-reference/endpoint/facebook/marketplace-search GET https://scrapebadger.com/v1/facebook/marketplace/search Keyword-search Facebook Marketplace with price, age, condition, delivery and sort filters. Search Facebook Marketplace by keyword in one location. Returns structured listings with price and currency, photos, place, condition subtitles, delivery types, sold/pending state and the seller actor. Marketplace has **no public Facebook API** — this endpoint is the only structured access to that inventory. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `macbook pro`. A Facebook Marketplace **location slug** (`nyc`, `la`, `london`, `newcastleupontyne`) or a **numeric Facebook place id** (`107486895947382`). Human-readable names such as `Durham, UK` are **not** accepted and return a `400` — see [Location targeting](#location-targeting) below. Search radius around the location, `1`–`500`. Facebook's own unit: kilometres in metric locales, miles in the US. Defaults to Facebook's 65 km / 40 mi. Minimum price, in the location's currency. Maximum price, in the location's currency. Only listings posted within the last N days, `1`–`30`. One of `best_match`, `price_ascend`, `price_descend`, `distance_ascend`, `creation_time_descend`. Comma-separated. One or more of `new`, `used_like_new`, `used_good`, `used_fair`. One of `local_pick_up`, `shipping`. Pagination cursor — the `end_cursor` from a previous response. ## Response Each `MarketplaceListing` includes `id`, `title`, `custom_title`, `url`, `price_formatted`, `price_amount`, `amount_with_offset`, `strikethrough_price`, `min_price`, `max_price`, `currency`, `primary_photo`, `photos[]`, `creation_time_utc`, `created_at`, `location_text`, `city`, `state`, `city_page_id`, `latitude`, `longitude`, `category_id`, `subtitles[]`, `delivery_types[]`, `attributes`, `is_sold`, `is_pending`, `is_live`, `is_hidden`, `seller` and `description`. `city_page_id` is the canonical Facebook place id for the listing's city, and can be passed straight back as a `location`. Facebook does **not** put coordinates on feed cards: `latitude` and `longitude` are `null` here for every listing, and the listing's place is carried by `location_text`, `city`, `state` and `city_page_id`. Coordinates come from [`/marketplace/item/{item_id}`](/api-reference/endpoint/facebook/marketplace-item). Number of listings in this page. Pass as `after` for the next page. Whether more listings are reachable. The query that was searched. The location value you sent. The location Facebook actually searched: `slug` (the slug or place id it resolved to), `latitude`, `longitude` and `radius`. Check these against your own geography before ingesting the listings. ## Location targeting Facebook does not error on an unknown `{location}` — it silently searches a **different place** and returns HTTP 200. Which place depends on the exit the request went out on, so the same bad input can come back as San Francisco, Maryland or Delaware inventory. This endpoint compares the location Facebook echoes back against the one you asked for and returns a `400 invalid_location` whenever they differ, so you are never billed for wrong-country inventory: ```json 400 invalid_location theme={null} { "error": "invalid_location", "detail": "'Durham, UK' is not a Facebook Marketplace location — Facebook searched '103787802993414' (39.2713, -76.735) instead. Pass a location slug (e.g. london, newcastleupontyne) or a numeric Facebook place id — the city_page_id on any listing is one. Human-readable names such as 'Durham, UK' are not accepted." } ``` Only places Facebook itself has minted a slug for resolve: `london` and `newcastleupontyne` do, `durham` and `sunderland` do not. To cover a town with no slug, search a nearby location that does have one and read `city_page_id` off the listings — those numeric place ids are valid `location` values: ```bash theme={null} # 1. search from a slug that resolves curl ".../marketplace/search?query=nintendo&location=newcastleupontyne" -H "X-API-Key: ..." # -> listings[].city_page_id: "107486895947382" (Whitley Bay), "112404765441676" (Sunderland), ... # 2. target that town directly, with your own radius curl ".../marketplace/search?query=nintendo&location=107486895947382&radius=10" -H "X-API-Key: ..." ``` A location Facebook recognises echoes back verbatim in `resolved_location.slug` (`newcastleupontyne` → `newcastleupontyne`), so you can also assert the coordinates fall inside your target geography before ingesting. Feed cards are truncated by Facebook: `description`, the full `photos[]` gallery and `attributes` are reliably populated only on [`/marketplace/item/{item_id}`](/api-reference/endpoint/facebook/marketplace-item). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/facebook/marketplace/search?query=macbook%20pro&location=nyc&max_price=1200&sort_by=creation_time_descend" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/facebook/marketplace/search?" + new URLSearchParams({ query: "macbook pro", location: "nyc", max_price: "1200", sort_by: "creation_time_descend", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/facebook/marketplace/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "query": "macbook pro", "location": "nyc", "max_price": 1200, "sort_by": "creation_time_descend", }, ) data = res.json() ``` ```json Response theme={null} { "listings": [ { "id": "1284419203847561", "title": "MacBook Pro 14\" M3 Pro 18GB/512GB", "custom_title": null, "url": "https://www.facebook.com/marketplace/item/1284419203847561/", "price_formatted": "$1,150", "price_amount": "1150", "amount_with_offset": "115000", "strikethrough_price": "$1,399", "min_price": null, "max_price": null, "currency": "USD", "primary_photo": "https://scontent.xx.fbcdn.net/v/t45.5328-4/478213_n.jpg", "photos": [], "creation_time_utc": 1785312840.0, "created_at": "2026-07-27T14:54:00Z", "location_text": "Brooklyn, NY", "city": "Brooklyn", "state": "NY", "city_page_id": "108424145849621", "latitude": null, "longitude": null, "category_id": "electronics", "subtitles": ["Used - Like New"], "delivery_types": ["local_pick_up", "shipping"], "attributes": {}, "is_sold": false, "is_pending": false, "is_live": true, "is_hidden": false, "seller": { "id": "100004421887301", "name": "Daniel Ortiz", "url": "https://www.facebook.com/profile.php?id=100004421887301", "profile_picture": "https://scontent.xx.fbcdn.net/v/t1.30497-1/84628_n.jpg", "is_verified": false, "typename": "User" }, "description": null } ], "count": 1, "end_cursor": "AQHRb2xkX2N1cnNvcl9leGFtcGxlXzAwMQ==", "has_next_page": true, "query": "macbook pro", "location": "nyc", "resolved_location": { "slug": "nyc", "latitude": 40.7142, "longitude": -74.0064, "radius": 65 } } ``` Combine `days_since_listed=1` with `sort_by=creation_time_descend` to poll a location for fresh inventory without re-reading the whole feed. # Create Filter Rule Source: https://docs.scrapebadger.com/api-reference/endpoint/filter-rules/create-filter-rule post /v1/twitter/stream/filter-rules Create a new filter rule that monitors Twitter using an Advanced Search query at a configurable polling interval. Matching tweets are delivered via WebSocket and optionally via webhook. Pricing is based on the polling interval tier. # Delete Filter Rule Source: https://docs.scrapebadger.com/api-reference/endpoint/filter-rules/delete-filter-rule delete /v1/twitter/stream/filter-rules/{rule_id} Permanently delete a filter rule and stop all associated polling. This action cannot be undone. # Get Filter Rule Source: https://docs.scrapebadger.com/api-reference/endpoint/filter-rules/get-filter-rule get /v1/twitter/stream/filter-rules/{rule_id} Retrieve details of a specific filter rule by its ID. Returns full rule configuration, status, and pricing information. # Get Filter Rule Logs Source: https://docs.scrapebadger.com/api-reference/endpoint/filter-rules/get-filter-rule-logs get /v1/twitter/stream/filter-rules/{rule_id}/logs List tweet delivery logs for a specific filter rule. Shows each detected tweet with detection latency, delivery status, and webhook response details. # Get Filter Rule Pricing Source: https://docs.scrapebadger.com/api-reference/endpoint/filter-rules/get-filter-rule-pricing get /v1/twitter/stream/filter-rules-pricing Retrieve the pricing tiers for filter rules. Each tier defines a maximum polling interval and the corresponding credit cost per rule per day. Use this to estimate costs before creating filter rules. # List Filter Rules Source: https://docs.scrapebadger.com/api-reference/endpoint/filter-rules/list-filter-rules get /v1/twitter/stream/filter-rules List all filter rules for the authenticated API key. Supports pagination and optional filtering by status. # Update Filter Rule Source: https://docs.scrapebadger.com/api-reference/endpoint/filter-rules/update-filter-rule patch /v1/twitter/stream/filter-rules/{rule_id} Update an existing filter rule. All fields are optional; only provided fields will be updated. Changing the interval may affect the pricing tier. # Validate Filter Rule Query Source: https://docs.scrapebadger.com/api-reference/endpoint/filter-rules/validate-filter-rule post /v1/twitter/stream/filter-rules/validate Validate a Twitter Advanced Search query without creating a filter rule. Returns whether the query syntax is valid and any errors found. Use this to test queries before creating filter rules. # Ask Gemini Source: https://docs.scrapebadger.com/api-reference/endpoint/gemini/ask GET https://scrapebadger.com/v1/gemini/ask Send a prompt to the real gemini.google.com and get the answer as structured JSON, with citations anchored to character offsets in the answer text. Ask **the real `gemini.google.com`** a question anonymously and get the answer back as JSON — plus every web source Gemini retrieved, which of those it cited, and exactly which span of the answer each citation supports. Accepts `GET` (query params) or `POST` (JSON body) with identical fields. **Credits:** 20 This is a live answer, not a cache — with web search the call can take tens of seconds. Set your client timeout to at least 60 s. ## Authorization Your ScrapeBadger API key. ## Query Parameters The question to ask. Maximum **4,096 characters**. Each request is standalone — there is no conversation memory, so include all the context you need here. ISO-3166 alpha-2 egress country, e.g. `US`, `GB`, `DE`. Changes the localised results Gemini retrieves. Whether Gemini should ground the answer with a web search. One of: * `auto` — let Gemini decide (default). * `force` — instruct it to search the web. * `off` — answer from the model's own knowledge only. Check `web_search_triggered` in the response for what actually happened. **Not supported — returns `422`.** Signed-out Gemini refuses image questions, so this fails immediately and is never billed. Use [ChatGPT `/ask`](/api-reference/endpoint/chatgpt/ask) for image input. **Not supported — returns `422`.** Same as `image_url` above. Anonymous gemini.google.com neither reads nor GENERATES images — its logged-out page gates both behind a login — so no request to this endpoint can answer about a picture or return one it drew. `images` in the response is what the answer *displayed*. ## Response Echo of the prompt you sent. The answer as plain text. Citation offsets index into this string. The answer with its original Markdown formatting, when available. The sources Gemini actually referenced in the answer. Source URL. Page title. Snippet Gemini retrieved from the page. Hostname, e.g. `techcrunch.com`. Publisher/attribution label as shown by Gemini. Character offset in `answer` where the supported span begins. Character offset in `answer` where the supported span ends. The substring of `answer` this source supports. The **full** set Gemini retrieved — including results it looked at but did not cite. Empty when `web_search_triggered` is `false`. Result URL. Result title. Retrieved snippet. Hostname. Publisher/attribution label. Whether this result made it into `citations`. Images the answer displayed — product shots, article art and other pictures a web-grounded answer pulls in. Favicon-sized assets are excluded. Never a generated image: see the warning above. Image URL. Alt text, when Gemini supplied one. Distinct hostnames across the cited sources — a quick view of who Gemini trusted. Whether Gemini **actually** grounded this answer with a web search. `true` when the render budget expired while Gemini was still writing, so `answer` is the partial text produced so far. Which model answered — a Gemini Flash-Lite build. Reported, not requestable. Identifier of the one-shot exchange. Not a handle you can continue from. Identifier of the answer message. Echo of the egress country used. Length of `answer` in characters. Number of entries in `citations`. End-to-end time to produce the answer, in milliseconds. Answer creation time as a Unix timestamp. Answer creation time as an ISO-8601 UTC string. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/gemini/ask?prompt=Which%20companies%20lead%20the%20web%20scraping%20API%20market%3F&country=US&web_search=force" \ -H "X-API-Key: YOUR_API_KEY" \ --max-time 60 ``` ```javascript Node.js theme={null} const res = await fetch("https://scrapebadger.com/v1/gemini/ask", { method: "POST", headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ prompt: "Which companies lead the web scraping API market?", country: "US", web_search: "force", }), signal: AbortSignal.timeout(60_000), }); const data = await res.json(); for (const c of data.citations) { console.log(`${c.domain} → "${c.matched_text}"`); } ``` ```python Python theme={null} import requests res = requests.post( "https://scrapebadger.com/v1/gemini/ask", headers={"X-API-Key": "YOUR_API_KEY"}, json={ "prompt": "Which companies lead the web scraping API market?", "country": "US", "web_search": "force", }, timeout=60, ) data = res.json() for c in data["citations"]: print(c["domain"], "→", data["answer"][c["start_index"]:c["end_index"]]) ``` ```json Response theme={null} { "prompt": "Which companies lead the web scraping API market?", "answer": "The web scraping API market in 2026 is led by a handful of infrastructure providers. Bright Data remains the largest by revenue, with a proxy network spanning residential and mobile exits. Oxylabs and Zyte compete directly on enterprise contracts, while newer entrants such as ScrapeBadger and ScrapingBee focus on per-endpoint APIs with predictable credit pricing.", "answer_markdown": "The web scraping API market in 2026 is led by a handful of infrastructure providers. **Bright Data** remains the largest by revenue, with a proxy network spanning residential and mobile exits. **Oxylabs** and **Zyte** compete directly on enterprise contracts, while newer entrants such as **ScrapeBadger** and **ScrapingBee** focus on per-endpoint APIs with predictable credit pricing.", "citations": [ { "url": "https://research.example.com/web-scraping-market-2026", "title": "Web Scraping Market Report 2026", "snippet": "Bright Data continues to hold the largest share of the commercial web data market...", "domain": "research.example.com", "attribution": "Example Research", "start_index": 103, "end_index": 213, "matched_text": "Bright Data remains the largest by revenue, with a proxy network spanning residential and mobile exits." }, { "url": "https://news.example.org/scraping-api-pricing-shakeup", "title": "The scraping API pricing shakeup", "snippet": "Credit-based per-endpoint pricing has become the default for newer vendors...", "domain": "news.example.org", "attribution": "Example News", "start_index": 214, "end_index": 366, "matched_text": "Oxylabs and Zyte compete directly on enterprise contracts, while newer entrants such as ScrapeBadger and ScrapingBee focus on per-endpoint APIs with predictable credit pricing." } ], "search_results": [ { "url": "https://research.example.com/web-scraping-market-2026", "title": "Web Scraping Market Report 2026", "snippet": "Bright Data continues to hold the largest share of the commercial web data market...", "domain": "research.example.com", "attribution": "Example Research", "cited": true }, { "url": "https://news.example.org/scraping-api-pricing-shakeup", "title": "The scraping API pricing shakeup", "snippet": "Credit-based per-endpoint pricing has become the default for newer vendors...", "domain": "news.example.org", "attribution": "Example News", "cited": true }, { "url": "https://forum.example.net/thread/best-scraping-api", "title": "Best scraping API in 2026? — discussion", "snippet": "Long thread comparing per-request costs across eight vendors...", "domain": "forum.example.net", "attribution": null, "cited": false } ], "source_domains": ["research.example.com", "news.example.org"], "web_search_triggered": true, "truncated": false, "model": "gemini-flash-lite", "conversation_id": "6a1f2c9e-3d54-4b17-9f0a-2c7de51b8a44", "message_id": "b03d7f18-5c2a-49e6-8f31-77d1c0a9e512", "country": "US", "answer_length": 366, "citation_count": 2, "latency_ms": 24817, "created_utc": 1754323200.0, "created_at": "2026-08-04T16:00:00Z" } ``` `search_results` is the full retrieved set; `citations` is the subset that made it into the answer. When `web_search_triggered` is `false`, both are empty and Gemini answered from its own knowledge — that is a valid response, not an error. ## Asking about an image **Gemini cannot answer about an image, and this endpoint no longer tries.** Passing `image_url` or `image_base64` returns `422` with `"code": "image_not_supported"`. Nothing is billed and no browser is spent. The upload itself works — the picture reaches Google and the prompt reaches the conversation — but signed-out sessions get `PERMISSION_DENIED` back from Gemini's own answer-generation call, so no answer is ever produced. The same request without a picture answers normally in a few seconds. This is a Google restriction on anonymous sessions, not a limit we impose, and there is no request shape that works around it. **Use [ChatGPT `/ask`](/api-reference/endpoint/chatgpt/ask) instead** — it takes `image_url` or `image_base64` and answers about the picture. ```bash Returns 422 theme={null} curl -X POST "https://scrapebadger.com/v1/gemini/ask" \ -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"prompt": "What is in this photo?", "image_url": "https://example.com/a.jpg"}' # {"detail":{"code":"image_not_supported", # "message":"Gemini refuses image questions for signed-out sessions # (PERMISSION_DENIED on its own generate RPC). # Use /v1/chatgpt/ask for image input."}} ``` Gemini is non-deterministic. The same prompt can return different wording and different sources on each call. For tracking, sample on a schedule and aggregate. # Brand Visibility Source: https://docs.scrapebadger.com/api-reference/endpoint/gemini/brand-visibility GET https://scrapebadger.com/v1/gemini/brand-visibility Ask Gemini a question and get a full AEO/GEO analysis of how your brand appears in the answer — mentions, position, share of voice against competitors, and whether your domain was cited. Ask **the real `gemini.google.com`** a buyer-intent question and get back both the answer **and** a structured analysis of how your brand fares in it: whether it was mentioned, how early, how often, how it compares to named competitors, and whether your domain was cited as a source. This is the **AEO / GEO** (Answer Engine / Generative Engine Optimisation) measurement that vendors like Profound, Otterly, Peec and AthenaHQ sell as a \$99–989/month subscription — here it is one 25-credit call, measured inside Gemini specifically. Accepts `GET` (query params) or `POST` (JSON body). **Credits:** 25 This is a live answer, not a cache — with web search the call can take tens of seconds. Set your client timeout to at least 60 s. ## Authorization Your ScrapeBadger API key. ## Query Parameters The question to ask Gemini — typically a buyer-intent prompt like `best web scraping API for e-commerce`. Maximum 4,096 characters. The brand name to look for in the answer, e.g. `ScrapeBadger`. Your domain, e.g. `scrapebadger.com`. Used to decide `cited`, `cited_urls` and `citation_rank`. Alternate spellings that also count as a mention of `brand` — e.g. `Scrape Badger,scrape-badger`. **Comma-separated on `GET`; a `string[]` on `POST`.** Competitor names to measure against, e.g. `Bright Data,Oxylabs,Zyte`. Drives `share_of_voice_pct` and the `competitors` array. **Comma-separated on `GET`; a `string[]` on `POST`.** ISO-3166 alpha-2 egress country. Visibility often differs by market. One of `auto`, `force`, `off`. **Defaults to `force`** here — visibility tracking usually wants Gemini to actually ground the answer. Check `web_search_triggered` for what happened. ## Response Echo of the prompt you sent. Echo of the brand you tracked. Echo of the domain you supplied. Whether the brand (or any alias) appears in the answer. How many times the brand or its aliases appear. Character offset of the first mention in `answer`. `null` when absent. How prominently the brand is placed: `1.0` = named at the very start of the answer, `0.0` = absent. Useful as a single trendable number. Brand mentions as a percentage of brand + competitor mentions. `0` when nobody is mentioned. Whether the brand's `domain` appears among the answer's cited sources. The cited URLs belonging to the brand's domain. 1-based rank of the brand's first cited URL within the citation list. `null` when not cited. One entry per competitor you named, in the order you supplied them. Competitor name as supplied. Whether it appears in the answer. How many times it appears. Character offset of its first mention. Whether a URL on its domain is cited. Its cited URLs. The answer text surrounding the first brand mention — ready to quote in a report. The full answer text. The sources Gemini referenced — same shape as [`/ask`](/api-reference/endpoint/gemini/ask). Source URL. Page title. Retrieved snippet. Hostname. Publisher/attribution label. Character offset in `answer` where the supported span begins. Character offset in `answer` where the supported span ends. The substring of `answer` this source supports. Whether Gemini actually grounded the answer with a web search. Which model answered — a Gemini Flash-Lite build. Echo of the egress country used. End-to-end time in milliseconds. Answer creation time as a Unix timestamp. Answer creation time as an ISO-8601 UTC string. ## Example ```bash cURL theme={null} curl -G "https://scrapebadger.com/v1/gemini/brand-visibility" \ -H "X-API-Key: YOUR_API_KEY" \ --data-urlencode "prompt=What is the best web scraping API for e-commerce data?" \ --data-urlencode "brand=ScrapeBadger" \ --data-urlencode "domain=scrapebadger.com" \ --data-urlencode "aliases=Scrape Badger,scrape-badger" \ --data-urlencode "competitors=Bright Data,Oxylabs,Zyte" \ --data-urlencode "country=US" \ --max-time 60 ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/gemini/brand-visibility", { method: "POST", headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ prompt: "What is the best web scraping API for e-commerce data?", brand: "ScrapeBadger", domain: "scrapebadger.com", aliases: ["Scrape Badger", "scrape-badger"], competitors: ["Bright Data", "Oxylabs", "Zyte"], country: "US", }), signal: AbortSignal.timeout(60_000), }, ); const data = await res.json(); console.log( `mentioned=${data.mentioned} sov=${data.share_of_voice_pct}% cited=${data.cited}`, ); ``` ```python Python theme={null} import requests res = requests.post( "https://scrapebadger.com/v1/gemini/brand-visibility", headers={"X-API-Key": "YOUR_API_KEY"}, json={ "prompt": "What is the best web scraping API for e-commerce data?", "brand": "ScrapeBadger", "domain": "scrapebadger.com", "aliases": ["Scrape Badger", "scrape-badger"], "competitors": ["Bright Data", "Oxylabs", "Zyte"], "country": "US", }, timeout=60, ) data = res.json() print(data["mentioned"], data["share_of_voice_pct"], data["citation_rank"]) ``` ```json Response theme={null} { "prompt": "What is the best web scraping API for e-commerce data?", "brand": "ScrapeBadger", "domain": "scrapebadger.com", "mentioned": true, "mention_count": 2, "first_position": 118, "position_score": 0.72, "share_of_voice_pct": 33.3, "cited": true, "cited_urls": ["https://scrapebadger.com/amazon"], "citation_rank": 2, "competitors": [ { "name": "Bright Data", "mentioned": true, "mention_count": 3, "first_position": 41, "cited": true, "cited_urls": ["https://brightdata.com/products/web-scraper"] }, { "name": "Oxylabs", "mentioned": true, "mention_count": 1, "first_position": 268, "cited": false, "cited_urls": [] }, { "name": "Zyte", "mentioned": false, "mention_count": 0, "first_position": null, "cited": false, "cited_urls": [] } ], "excerpt": "...for structured e-commerce data specifically, ScrapeBadger offers dedicated Amazon and eBay endpoints with per-request credit pricing, which avoids the proxy-bandwidth billing model...", "answer": "For e-commerce scraping in 2026 the strongest options are Bright Data, ScrapeBadger and Oxylabs. Bright Data has the widest proxy footprint, but for structured e-commerce data specifically, ScrapeBadger offers dedicated Amazon and eBay endpoints with per-request credit pricing, which avoids the proxy-bandwidth billing model. Oxylabs sits between the two on price.", "citations": [ { "url": "https://brightdata.com/products/web-scraper", "title": "Web Scraper API", "snippet": "Collect public web data at scale with our unblocking infrastructure...", "domain": "brightdata.com", "attribution": "Bright Data", "start_index": 84, "end_index": 132, "matched_text": "Bright Data has the widest proxy footprint" }, { "url": "https://scrapebadger.com/amazon", "title": "Amazon Scraper API", "snippet": "Product search, PDP detail, offers, reviews and bestsellers across 20 marketplaces...", "domain": "scrapebadger.com", "attribution": "ScrapeBadger", "start_index": 178, "end_index": 322, "matched_text": "ScrapeBadger offers dedicated Amazon and eBay endpoints with per-request credit pricing, which avoids the proxy-bandwidth billing model" } ], "web_search_triggered": true, "model": "gemini-flash-lite", "country": "US", "latency_ms": 27342, "created_utc": 1754323200.0, "created_at": "2026-08-04T16:00:00Z" } ``` `position_score` is the single number to trend over time: `1.0` means the brand was named at the very start of the answer, `0.0` means it was absent. Combine it with `share_of_voice_pct` and `cited` for a full picture. Because Gemini is non-deterministic, one call is a sample, not a measurement. Run the same prompt on a schedule (daily, or several times a day for competitive prompts) and track the moving average of `position_score` and `share_of_voice_pct`. Vary `country` to see how visibility differs by market. # Get Place Details Source: https://docs.scrapebadger.com/api-reference/endpoint/geo/get-place-details get /v1/twitter/geo/places/{place_id} Get detailed information about a specific geographic place. Returns comprehensive place data including full name, country, place type, bounding box coordinates, and additional attributes. Use place IDs obtained from the geo search endpoint. # Search Places Source: https://docs.scrapebadger.com/api-reference/endpoint/geo/search-places get /v1/twitter/geo/search Search for geographic places that can be attached to tweets. At least one of `query`, `lat`/`long`, or `ip` must be provided. Results can be filtered by granularity (neighborhood, city, admin, country). Useful for geo-tagging and location-based analysis. # Get Advertiser Source: https://docs.scrapebadger.com/api-reference/endpoint/google-ads-transparency/get-advertiser GET https://scrapebadger.com/v1/google/ads/advertiser Advertiser identity plus Google's disclosed spend, ad-format mix and per-day spend curve for one region. Advertiser identity plus the spend Google discloses for one region: total spend and currency, ad count, the share of spend by creative format, and a per-day spend curve across the requested window. **Credits:** 5 Spend disclosure exists for **political advertisers**. A commercial advertiser with no disclosure returns `404` rather than a row of zeroes. ## Authorization Your ScrapeBadger API key. ## Query Parameters Advertiser ID, e.g. `AR01614014350098432001`. Resolve a name with [`/ads/advertisers`](/api-reference/endpoint/google-ads-transparency/search-advertisers). ISO 3166-1 alpha-2 region. Disclosure is region-scoped — `anywhere` returns nothing, so it falls back to `US`. Window start, `YYYY-MM-DD`. Defaults to 30 days ago. Window end, `YYYY-MM-DD`. Defaults to today. ## Response Ads disclosed for the region. e.g. `USD`. Disclosed spend for the region and window. Echo of the requested window start. Echo of the requested window end. The advertiser's Transparency Center page. Share of disclosed spend by creative format. `TEXT`, `IMAGE` or `VIDEO`. Fraction of spend, `0`–`1`. One point per day of the window. `YYYYMMDD`, as Google returns it. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google/ads/advertiser?advertiser_id=AR01614014350098432001®ion=US&start_date=2026-07-01&end_date=2026-07-31" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/google/ads/advertiser?" + new URLSearchParams({ advertiser_id: "AR01614014350098432001", region: "US", start_date: "2026-07-01", end_date: "2026-07-31", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const advertiser = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/google/ads/advertiser", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "advertiser_id": "AR01614014350098432001", "region": "US", "start_date": "2026-07-01", "end_date": "2026-07-31", }, ) advertiser = res.json() ``` ```json Response theme={null} { "advertiser_id": "AR01614014350098432001", "advertiser_name": "Example Campaign Committee", "region": "US", "verified": true, "ads_count": 318, "currency": "USD", "spend": 1284500.0, "start_date": "2026-07-01", "end_date": "2026-07-31", "details_link": "https://adstransparency.google.com/advertiser/AR01614014350098432001", "ad_mix": [ { "format": "VIDEO", "share": 0.62, "spend": 796390.0 }, { "format": "IMAGE", "share": 0.27, "spend": 346815.0 }, { "format": "TEXT", "share": 0.11, "spend": 141295.0 } ], "spend_by_date": [ { "date": "20260701", "share": 0.031, "spend": 39819.5 }, { "date": "20260702", "share": 0.028, "spend": 35966.0 } ] } ``` ## Errors | Status | Meaning | | - | - | | `400` | Unknown region, or a malformed date. | | `404` | No Ads Transparency disclosure for that advertiser, region and window. | | `502` | Upstream Transparency Center failure — **not billed**. | # Get Ad Creative Source: https://docs.scrapebadger.com/api-reference/endpoint/google-ads-transparency/get-creative GET https://scrapebadger.com/v1/google/ads/creative Full detail for one Ads Transparency Center creative — media, every rendered size variation, run dates and optional political disclosure. Full detail for a single creative: media, rendered size variations, first- and last-shown dates and the target domain. Optionally attaches the advertiser's political-ad spend disclosure for the region. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Advertiser ID, e.g. `AR01614014350098432001`. Creative ID, e.g. `CR10484731423840108545`. Take both ids from [`/ads/search`](/api-reference/endpoint/google-ads-transparency/search-ads). ISO 3166-1 alpha-2 region, or `anywhere`. Also fetch the advertiser's political-ad spend disclosure for `region`. Costs one extra upstream call and is empty for non-political advertisers. ## Response `TEXT`, `IMAGE` or `VIDEO`. Each rendered size of the creative. Present only with `political=true` and a disclosing advertiser. Exact disclosed spend for the region. Per-creative disclosure range — not yet populated. Not yet populated. Not yet populated. Not yet populated. `region`, `currency`, `spend`, `ads_count`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google/ads/creative?advertiser_id=AR01614014350098432001&creative_id=CR10484731423840108545®ion=US" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/google/ads/creative?" + new URLSearchParams({ advertiser_id: "AR01614014350098432001", creative_id: "CR10484731423840108545", region: "US", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const creative = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/google/ads/creative", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "advertiser_id": "AR01614014350098432001", "creative_id": "CR10484731423840108545", "region": "US", }, ) creative = res.json() ``` ```json Response theme={null} { "creative_id": "CR10484731423840108545", "advertiser_id": "AR01614014350098432001", "advertiser_name": "Nike, Inc.", "target_domain": "nike.com", "region": "US", "format": "IMAGE", "media_url": "https://tpc.googlesyndication.com/simgad/example", "first_shown_utc": 1749513600, "first_shown_at": "2026-06-10T00:00:00Z", "last_shown_utc": 1754870400, "last_shown_at": "2026-08-11T00:00:00Z", "days_shown": 63, "details_link": "https://adstransparency.google.com/advertiser/AR01614014350098432001/creative/CR10484731423840108545", "variations": [ { "media_url": "https://tpc.googlesyndication.com/simgad/example-300x250", "preview_html": "
…
", "width": 300, "height": 250 }, { "media_url": "https://tpc.googlesyndication.com/simgad/example-728x90", "width": 728, "height": 90 } ], "political": null } ``` A missing political disclosure never fails the lookup — the creative parsed fine, so `political` simply comes back `null`. ## Errors | Status | Meaning | | - | - | | `400` | Unknown region. | | `404` | No such creative for that advertiser. | | `502` | Upstream Transparency Center failure — **not billed**. | # Search Ad Creatives Source: https://docs.scrapebadger.com/api-reference/endpoint/google-ads-transparency/search-ads GET https://scrapebadger.com/v1/google/ads/search Search Google Ads Transparency Center creatives by advertiser id or verified domain, with format and date-window filtering. Search creatives by advertiser or domain. One of `advertiser_id` or `query` is required. **Credits:** 10 Free-text `query` is **domain-based** — it matches verified advertiser domains like `nike.com`, not brand names. For a brand name, resolve it first with [`/ads/advertisers`](/api-reference/endpoint/google-ads-transparency/search-advertisers) and pass the resulting `advertiser_id`. ## Authorization Your ScrapeBadger API key. ## Query Parameters Advertiser ID as shown in the Transparency Center URL, e.g. `AR01614014350098432001`. Required unless `query` is given. Free text — a verified advertiser domain such as `tesla.com`. Required unless `advertiser_id` is given. ISO 3166-1 alpha-2 region the ad was served in, or `anywhere` for no region filter. Surface the ad ran on: `SEARCH`, `MAPS`, `PLAY`, `SHOPPING` or `YOUTUBE`. **Validated but not applied** — see `filters_applied.platform`. Creative format: `TEXT`, `IMAGE` or `VIDEO`. Applied over the returned page. `YYYY-MM-DD`. Keeps creatives still running on or after this date. `YYYY-MM-DD`. Keeps creatives first shown on or before this date. Restrict to political ads. **Validated but not applied** — see `filters_applied.political`. Results per page, `1`–`100`. `next_page_token` from a previous response. ## Response The region requested. Google's reported total for the advertiser or domain, when it sends one. Creatives in this response **after** the format and date filters — can be smaller than `num` while `next_page_token` is still set. Pass as `cursor` for the next page. `null` on the last page. Which filters were honoured: `region`, `advertiser_id`, `query`, `format`, `date_range`, `platform`, `political`. `platform` and `political` are always `false`. e.g. `CR10484731423840108545`. The advertiser's verified domain. `TEXT`, `IMAGE` or `VIDEO`. Image or video asset, for image and video creatives. Google's rendered preview markup. ISO 8601 UTC. The Transparency Center page for this creative. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google/ads/search?advertiser_id=AR01614014350098432001®ion=US&format=VIDEO&num=40" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/google/ads/search?" + new URLSearchParams({ advertiser_id: "AR01614014350098432001", region: "US", format: "VIDEO", num: "40", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/google/ads/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "advertiser_id": "AR01614014350098432001", "region": "US", "format": "VIDEO", "num": 40, }, ) data = res.json() ``` ```json Response theme={null} { "region": "US", "total_results": 1284, "returned_results": 2, "next_page_token": "CkgKRkFSMDE2MTQwMTQzNTAwOTg0MzIwMDEQZBgB", "filters_applied": { "region": true, "advertiser_id": true, "query": false, "format": true, "date_range": false, "platform": false, "political": false }, "creatives": [ { "creative_id": "CR10484731423840108545", "advertiser_id": "AR01614014350098432001", "advertiser_name": "Nike, Inc.", "target_domain": "nike.com", "format": "VIDEO", "media_url": "https://www.youtube.com/embed/dQw4w9WgXcQ", "preview_html": "", "first_shown_utc": 1749513600, "first_shown_at": "2026-06-10T00:00:00Z", "last_shown_utc": 1754870400, "last_shown_at": "2026-08-11T00:00:00Z", "days_shown": 63, "details_link": "https://adstransparency.google.com/advertiser/AR01614014350098432001/creative/CR10484731423840108545" }, { "creative_id": "CR17738822901234567890", "advertiser_id": "AR01614014350098432001", "advertiser_name": "Nike, Inc.", "target_domain": "nike.com", "format": "VIDEO", "media_url": "https://www.youtube.com/embed/abc123XYZ", "first_shown_utc": 1752105600, "first_shown_at": "2026-07-10T00:00:00Z", "last_shown_utc": 1754784000, "last_shown_at": "2026-08-10T00:00:00Z", "days_shown": 32, "details_link": "https://adstransparency.google.com/advertiser/AR01614014350098432001/creative/CR17738822901234567890" } ] } ``` The date window matches on **overlap**, not on start: a creative shown 2026-01-01 to 2026-06-01 matches a March query, because callers ask "what was running then", not "what started then". ## Errors | Status | Meaning | | - | - | | `400` | Neither `advertiser_id` nor `query` given; unknown `platform`, `format`, region or date. | | `502` | Upstream Transparency Center failure — **not billed**. | # Search Advertisers Source: https://docs.scrapebadger.com/api-reference/endpoint/google-ads-transparency/search-advertisers GET https://scrapebadger.com/v1/google/ads/advertisers Resolve an advertiser name or domain to Google Ads Transparency Center advertiser IDs. Resolve an advertiser name or domain to the `advertiser_id` the other endpoints take. This is the **entry point for brand-name lookups** — free-text search on [`/ads/search`](/api-reference/endpoint/google-ads-transparency/search-ads) is domain-based and will not find a brand by name. **Credits:** 5 — or 15 with `fuzzy=true`. An empty result is not billed. Google's own matching has **no typo tolerance**: advertiser names match by word prefix (`ruff wear` finds *Ruff Wear, Inc.*, `ruffwear` does not) and domains by substring (`uffwear` finds `ruffwear.com`). A single typo — `rufwear`, `ruffwearp` — returns nothing. Set `fuzzy=true` to find misspelled and look-alike advertisers. ## Authorization Your ScrapeBadger API key. ## Query Parameters Advertiser name or domain to autocomplete. Minimum 2 characters. Echoed on the response only. Use `country` to filter advertisers. Advertisers to return, `1`–`3000`. 3000 is Google's own per-call ceiling; one call returns every match up to it, so advertisers do not page. Domain rows to return, `0`–`100`. They follow the advertiser rows. ISO 3166-1 alpha-2. Only advertisers registered in this country. Domain rows are not filtered. `next_page_token` from a previous response: the next page of domain rows. Cannot be combined with `fuzzy`. Find misspelled and look-alike advertisers. Searches up to 7 variants of the query (shorter prefixes, overlapping halves, swapped leading letters), resolves the closest look-alike domains to the advertisers running ads on them, drops weak matches, and ranks every row by `similarity`. Billed 15 credits (3 lookups), however many variants run. ## Response Echo of the requested text. The applied `country` filter, upper-cased, or null. `fuzzy=true` only: the query variants that were searched. `fuzzy=true` only: variants whose upstream call failed. The rest are still returned. Pass as `cursor` for the next page of domain rows. Pass to `/ads/search` and `/ads/advertiser`. The advertiser's own registered region, when disclosed. Verified domain — a bare-domain suggestion has this but no name. Whether Google has verified the advertiser's identity. The advertiser's Transparency Center page. `fuzzy=true` only: 0–1 closeness to the query (1 = exact). `fuzzy=true` only: the variant that surfaced this row, or the look-alike domain an advertiser was found behind. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google/ads/advertisers?query=nike®ion=US&num=10" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/google/ads/advertisers?" + new URLSearchParams({ query: "nike", region: "US", num: "10" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { advertisers } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/google/ads/advertisers", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "nike", "region": "US", "num": 10}, ) advertisers = res.json()["advertisers"] ``` ```json Response theme={null} { "query": "nike", "region": "US", "advertisers": [ { "advertiser_id": "AR01614014350098432001", "name": "Nike, Inc.", "region": "US", "domain": "nike.com", "verified": true, "ads_count": 1284, "details_link": "https://adstransparency.google.com/advertiser/AR01614014350098432001" }, { "advertiser_id": "AR08811772660094828545", "name": "Nike Deutschland GmbH", "region": "DE", "domain": "nike.com", "verified": true, "ads_count": 402, "details_link": "https://adstransparency.google.com/advertiser/AR08811772660094828545" } ] } ``` A brand often has one advertiser entity per country. Check the suggestion's own `region` before assuming the first hit is the one running ads in the market you care about. ## Finding look-alike advertisers `fuzzy=true` is built for brand protection. Impersonators rarely advertise under the brand's name. They register under a personal or unrelated name and point ads at a look-alike domain, so no name search reaches them. The fuzzy mode resolves those domains to the advertiser behind them: ```bash theme={null} curl "https://scrapebadger.com/v1/google/ads/advertisers?query=rufwear&fuzzy=true" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json theme={null} { "query": "rufwear", "fuzzy": true, "variants": ["rufwear", "ruf", "rufw", "fwear", "urfwear", "rfuwear", "ruwfear"], "variants_failed": [], "advertisers": [ { "advertiser_id": "AR01181731973429723137", "name": "Ruff Wear, Inc.", "domain": "ruffwear.ca", "similarity": 0.875, "matched_query": "ruf" }, { "advertiser_id": "AR14220847488281083905", "name": "葛茂朋", "domain": "ruffwearcf.shop", "similarity": 0.814, "matched_query": "ruffwearcf.shop" }, { "advertiser_id": null, "domain": "ruffwear.com", "similarity": 0.875, "matched_query": "ruf" }, { "advertiser_id": null, "domain": "ruffwearcf.shop", "similarity": 0.814, "matched_query": "fwear" } ] } ``` The same query without `fuzzy` returns `"advertisers": []`. Pass any `advertiser_id` to [`/ads/search`](/api-reference/endpoint/google-ads-transparency/search-ads) to see the ads. ## Errors | Status | Meaning | | - | - | | `400` | Unknown `country`, or `cursor` combined with `fuzzy`. | | `422` | `query` shorter than 2 characters, or `num` / `num_domains` out of range. | | `502` | Upstream Transparency Center failure — **not billed**. | # Browse a Category Source: https://docs.scrapebadger.com/api-reference/endpoint/google-play/browse-category GET https://scrapebadger.com/v1/google-play/categories/{category_id} Every app across a Google Play category page's editorial rails, deduped and in Play's own order. Browse a Play category. Returns every app across all of the category page's editorial rails ("Popular", "Be the first to play", genre spotlights), deduped and in the order Play ranked them — around 100 apps for a broad category like `GAME`. **Credits:** 5 This is the **working alternative to top charts**. Play renders the ranked top-chart list client-side, so [`/collections/{collection}`](/api-reference/endpoint/google-play/get-collection) answers `422`. A category browse is server-rendered and returns real data. ## Authorization Your ScrapeBadger API key. ## Path Parameters Play category id, e.g. `SOCIAL`, `GAME_PUZZLE`, `APPLICATION`. The full list is at [`/categories`](/api-reference/endpoint/google-play/list-categories) (free); it also matches `genre_id` on an app detail record. ## Query Parameters Play storefront (`gl`). Play content language (`hl`). ## Response The category id requested. The Play URL the apps were read from. Apps returned. Apps in the category — same shape as [search results](/api-reference/endpoint/google-play/search). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google-play/categories/GAME_PUZZLE?country=US&lang=en" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/google-play/categories/GAME_PUZZLE?" + new URLSearchParams({ country: "US", lang: "en" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { apps } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/google-play/categories/GAME_PUZZLE", headers={"X-API-Key": "YOUR_API_KEY"}, params={"country": "US", "lang": "en"}, ) apps = res.json()["apps"] ``` ```json Response theme={null} { "query": "GAME_PUZZLE", "url": "https://play.google.com/store/apps/category/GAME_PUZZLE?hl=en&gl=US", "result_count": 96, "apps": [ { "app_id": "com.king.candycrushsaga", "title": "Candy Crush Saga", "developer": "King", "summary": "Switch and match Candies in this tasty puzzle adventure", "icon": "https://play-lh.googleusercontent.com/example=w240-h480-rw", "score": 4.6, "score_text": "4.6", "installs": "1,000,000,000+", "genre": "Puzzle", "content_rating": "Everyone", "price": { "price": 0.0, "currency": "USD", "price_text": "Free", "is_free": true }, "url": "https://play.google.com/store/apps/details?id=com.king.candycrushsaga" } ] } ``` ## Errors | Status | Meaning | | - | - | | `404` | No apps in that category for the storefront — usually an unknown category id. | | `422` | Play returned no usable data — **not billed**. Retry. | # Get App Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/google-play/get-app GET https://scrapebadger.com/v1/google-play/apps/{app_id} Full Google Play app detail — ratings histogram, install bands, pricing and IAP range, developer legal entity, media, version metadata, Data Safety and the permission tree. Everything Play's product page carries, in one fetch: the description, the 1–5 star histogram, install bands, price and in-app-purchase range, the developer's contact and legal entity, media, release and update timestamps, the Data Safety declaration, the permission tree and the similar-apps rail. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Android package id, e.g. `com.whatsapp`. It is the `id` query parameter of a `play.google.com/store/apps/details?id=...` URL. ## Query Parameters Play storefront (`gl`) — sets pricing and availability. Play content language (`hl`), e.g. `en` or `pt-BR`. ## Response Android package id. Full store description. One-line pitch. Publisher and the legal entity Play discloses beneath it — the two differ more often than not. e.g. `WhatsApp LLC`. Numeric id, for [`/developers/{id}`](/api-reference/endpoint/google-play/get-developer). Postal address from the legal block. e.g. `Meta Platforms, Inc.`. Average rating. Total ratings. Total written reviews. `one_star` … `five_star` — the bar chart Play renders. Install band, e.g. `5,000,000,000+`. e.g. `5B+`. The "#1 top free communication" badge when the app carries one — `rank`, `chart`. `price`, `currency`, `price_text`, `is_free`. e.g. `$0.99 - $99.99 per item`. Category id, e.g. `COMMUNICATION`. Release date as displayed. Unix seconds. ISO 8601 UTC. What's new in this version. Play's Data Safety card — `title`, `description` per row. `group`, `icon_url`, `permissions[]` — the same tree [`/permissions`](/api-reference/endpoint/google-play/get-permissions) returns. Link to the full similar-apps cluster. The detail page's similar-apps rail. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google-play/apps/com.whatsapp?country=US&lang=en" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/google-play/apps/com.whatsapp?" + new URLSearchParams({ country: "US", lang: "en" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const app = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/google-play/apps/com.whatsapp", headers={"X-API-Key": "YOUR_API_KEY"}, params={"country": "US", "lang": "en"}, ) app = res.json() ``` ```json Response theme={null} { "app_id": "com.whatsapp", "title": "WhatsApp Messenger", "url": "https://play.google.com/store/apps/details?id=com.whatsapp&hl=en&gl=US", "summary": "Simple. Reliable. Private.", "description": "WhatsApp from Meta is a FREE messaging and video calling app...", "developer": { "name": "WhatsApp LLC", "developer_id": "5700313618786177705", "url": "https://play.google.com/store/apps/dev?id=5700313618786177705", "email": "androidsupport@support.whatsapp.com", "website": "https://www.whatsapp.com/", "address": "1601 Willow Road Menlo Park, CA 94025 United States", "legal_name": "WhatsApp LLC", "legal_email": "androidsupport@support.whatsapp.com" }, "score": 4.3, "score_text": "4.3", "ratings": 195204118, "reviews": 5820113, "histogram": { "one_star": 17842011, "two_star": 4210338, "three_star": 8930442, "four_star": 20114876, "five_star": 144106451 }, "installs": "10,000,000,000+", "installs_short": "10B+", "min_installs": 10000000000, "max_installs": 20000000000, "chart_rank": { "rank": "#3", "chart": "top free communication" }, "price": { "price": 0.0, "currency": "USD", "price_text": "Free", "is_free": true }, "offers_iap": false, "contains_ads": false, "ad_supported": false, "genre": "Communication", "genre_id": "COMMUNICATION", "content_rating": "Everyone", "icon": "https://play-lh.googleusercontent.com/example=w240-h480-rw", "screenshots": ["https://play-lh.googleusercontent.com/shot1=w720"], "released": "Jan 1, 2010", "released_utc": 1262304000.0, "released_at": "2010-01-01T00:00:00Z", "updated_utc": 1754870400.0, "updated_at": "2026-08-11T00:00:00Z", "version": "2.26.16.72", "android_version": "5.0", "android_version_text": "5.0 and up", "recent_changes": "• Bug fixes and performance improvements.", "privacy_policy": "https://www.whatsapp.com/legal/privacy-policy", "data_safety": [ { "title": "This app may share these data types with third parties", "description": "Location, Personal info and 5 others" }, { "title": "Data is encrypted in transit", "description": null } ], "permissions": [ { "group": "Camera", "icon_url": "https://play-lh.googleusercontent.com/cam", "permissions": ["take pictures and videos"] } ], "similar_apps_url": "https://play.google.com/store/apps/collection/cluster?clp=example", "similar_apps": [ { "app_id": "org.telegram.messenger", "title": "Telegram", "developer": "Telegram FZ-LLC", "score": 4.3, "installs": "1,000,000,000+", "price": { "price": 0.0, "currency": "USD", "price_text": "Free", "is_free": true } } ] } ``` A field Play does not render for that app or storefront comes back `null` (or an empty list) rather than being omitted — `chart_rank` and `iap_range` are the usual absentees. # Top Charts Source: https://docs.scrapebadger.com/api-reference/endpoint/google-play/get-collection GET https://scrapebadger.com/v1/google-play/collections/{collection} Google Play top charts — currently unavailable, because Play renders the ranking client-side. Returns 422 (not billed). Top charts for a category and country. **This endpoint currently returns `422` for every request, and `422` is not billed.** Google Play no longer server-renders the top-chart ranking. The category page carries the chart *tabs* — their ids and labels are in the payload — but the item list is empty and filled in client-side. That was confirmed across `GAME`/US, `COMMUNICATION`/US and `GAME`/DE, so it is Play's rendering model and not a per-page fluke. The legacy `/store/apps/collection/{id}` URLs still answer `200` but serve an empty shell. Use [`/categories/{category_id}`](/api-reference/endpoint/google-play/browse-category) for that category's apps in Play's own order. The route ships reading the chart cluster the correct way, so it starts returning data unchanged if Google restores server-side rendering. Returning the page's editorial rails instead would charge you for a ranking you did not ask for and could not distinguish from the real one. **Credits:** 5 when it returns data. `422` is **not billed**. ## Authorization Your ScrapeBadger API key. ## Path Parameters `topselling_free`, `topselling_paid` or `topgrossing`. Anything else is a `400`. ## Query Parameters Category to rank within, e.g. `GAME` or `SOCIAL`. Defaults to all apps. See [`/categories`](/api-reference/endpoint/google-play/list-categories). Play storefront (`gl`). Play content language (`hl`). ## Response The collection requested. The Play URL the chart was read from. Apps returned. Ranked apps — same shape as [search results](/api-reference/endpoint/google-play/search), in chart order. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google-play/collections/topselling_free?category=GAME&country=US" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/google-play/collections/topselling_free?" + new URLSearchParams({ category: "GAME", country: "US" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); // Currently 422 — fall back to /categories/GAME. ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/google-play/collections/topselling_free", headers={"X-API-Key": "YOUR_API_KEY"}, params={"category": "GAME", "country": "US"}, ) # Currently 422 — fall back to /categories/GAME. ``` ```json Response (current behaviour) theme={null} { "detail": "Google Play renders the topselling_free chart client-side; no server-side ranking is available for category GAME. Use /categories/GAME for that category's apps." } ``` ## Errors | Status | Meaning | | - | - | | `400` | Unknown collection id. | | `422` | Play renders this chart client-side — **not billed**. Retrying will not help; use `/categories/{id}`. | | `502` | Unexpected upstream failure — **not billed**. | # Get Developer Apps Source: https://docs.scrapebadger.com/api-reference/endpoint/google-play/get-developer GET https://scrapebadger.com/v1/google-play/developers/{developer} A Google Play developer's published apps, by numeric developer id or display name. A developer's published apps. Play serves developer pages on two different paths and picks by id type — `/store/apps/dev` for the numeric id, `/store/apps/developer` for the display name — so this route chooses the path from the id shape rather than making you know which one you hold. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Either the numeric id from an app's `developer.developer_id` (e.g. `5700313618786177705`) or the display name from `developer.name` (e.g. `WhatsApp LLC`). URL-encode names containing spaces. ## Query Parameters Play storefront (`gl`). Play content language (`hl`). ## Response The developer id or name requested. The Play URL the catalogue was read from. Apps returned. The developer's apps — same shape as [search results](/api-reference/endpoint/google-play/search). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google-play/developers/5700313618786177705?country=US" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/google-play/developers/" + encodeURIComponent("WhatsApp LLC") + "?country=US", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { apps } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/google-play/developers/5700313618786177705", headers={"X-API-Key": "YOUR_API_KEY"}, params={"country": "US"}, ) apps = res.json()["apps"] ``` ```json Response theme={null} { "query": "5700313618786177705", "url": "https://play.google.com/store/apps/dev?id=5700313618786177705&hl=en&gl=US", "result_count": 3, "apps": [ { "app_id": "com.whatsapp", "title": "WhatsApp Messenger", "developer": "WhatsApp LLC", "score": 4.3, "installs": "10,000,000,000+", "genre": "Communication", "price": { "price": 0.0, "currency": "USD", "price_text": "Free", "is_free": true }, "url": "https://play.google.com/store/apps/details?id=com.whatsapp" }, { "app_id": "com.whatsapp.w4b", "title": "WhatsApp Business", "developer": "WhatsApp LLC", "score": 4.2, "installs": "500,000,000+", "genre": "Business", "price": { "price": 0.0, "currency": "USD", "price_text": "Free", "is_free": true }, "url": "https://play.google.com/store/apps/details?id=com.whatsapp.w4b" } ] } ``` Play server-renders only the first rail of a large catalogue — around 10 apps for a publisher with dozens. The rest load on scroll behind a cluster RPC Google has closed off, so they are not reachable. ## Errors | Status | Meaning | | - | - | | `404` | No apps for that developer in the storefront — usually a wrong id form. | | `422` | Play returned no usable data — **not billed**. Retry. | # Get App Permissions Source: https://docs.scrapebadger.com/api-reference/endpoint/google-play/get-permissions GET https://scrapebadger.com/v1/google-play/apps/{app_id}/permissions Every Android permission an app declares, grouped the way Google Play groups them. Every Android permission the app declares, grouped as Play groups them. Cheaper than a full detail fetch because it reads a single Play RPC. **Credits:** 3 ## Authorization Your ScrapeBadger API key. ## Path Parameters Android package id, e.g. `com.whatsapp`. ## Query Parameters Play content language (`hl`) — sets the language of the group and permission labels. ## Response Permission groups returned. e.g. `Camera`, `Location`, `Other`. Play's group icon. Individual permissions in the group. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google-play/apps/com.whatsapp/permissions?lang=en" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/google-play/apps/com.whatsapp/permissions?lang=en", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { permission_groups } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/google-play/apps/com.whatsapp/permissions", headers={"X-API-Key": "YOUR_API_KEY"}, params={"lang": "en"}, ) groups = res.json()["permission_groups"] ``` ```json Response theme={null} { "app_id": "com.whatsapp", "result_count": 3, "permission_groups": [ { "group": "Camera", "icon_url": "https://play-lh.googleusercontent.com/perm-camera", "permissions": ["take pictures and videos"] }, { "group": "Location", "icon_url": "https://play-lh.googleusercontent.com/perm-location", "permissions": ["approximate location (network-based)", "precise location (GPS and network-based)"] }, { "group": "Other", "icon_url": "https://play-lh.googleusercontent.com/perm-other", "permissions": ["view network connections", "full network access", "run at startup"] } ] } ``` The same tree is already on the [app detail](/api-reference/endpoint/google-play/get-app) response as `permissions` — use this route when you want permissions alone and do not want to pay 5 credits for the whole record. # Get App Reviews Source: https://docs.scrapebadger.com/api-reference/endpoint/google-play/get-reviews GET https://scrapebadger.com/v1/google-play/apps/{app_id}/reviews Paginated Google Play user reviews with developer replies, sorted by newest, rating or helpfulness. Paginated user reviews from Play's own review RPC — up to 150 per page, with developer replies where they exist. Play paginates by continuation token, not by page number: pass the previous response's `next_page_token` as `page_token`. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Android package id, e.g. `com.whatsapp`. ## Query Parameters Play storefront (`gl`). Play content language (`hl`) — reviews are returned in this language's feed. Review ordering: `newest`, `rating` or `helpfulness`. Each returns a measurably different first page. Reviews per page, `1`–`150`. Play silently truncates beyond 150, so the ceiling is enforced rather than letting you pay for results that will not arrive. Continuation token from a previous response's `next_page_token`. ## Response The ordering used. Reviews in this page. Pass as `page_token` for the next page. `null` on the last page. Star rating, `1`–`5`. Helpful votes. App version reviewed. Posted, Unix seconds. Posted, ISO 8601 UTC. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google-play/apps/com.whatsapp/reviews?sort=newest&count=40" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/google-play/apps/com.whatsapp/reviews?" + new URLSearchParams({ sort: "newest", count: "40" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { reviews, next_page_token } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/google-play/apps/com.whatsapp/reviews", headers={"X-API-Key": "YOUR_API_KEY"}, params={"sort": "newest", "count": 40}, ) page = res.json() ``` ```json Response theme={null} { "app_id": "com.whatsapp", "sort": "newest", "result_count": 40, "next_page_token": "CpEBCo4BQU9xcFRPRXhhbXBsZVRva2VuQmFzZTY0", "reviews": [ { "review_id": "0f2c1a9e-5d31-4a77-9f0c-3b2a1e6d8c44", "user_name": "Priya S.", "user_image": "https://play-lh.googleusercontent.com/a/user=mo", "score": 5, "text": "Calls are clear even on a weak connection. The new sticker picker is great.", "thumbs_up": 42, "review_created_version": "2.26.16.72", "at_utc": 1754956800.0, "at": "2026-08-12T00:00:00Z", "reply_author": null, "reply_content": null, "replied_utc": null, "replied_at": null }, { "review_id": "b71d4e02-8c6a-4c19-a0f5-71d9e2f3c118", "user_name": "Marco R.", "score": 2, "text": "Backups keep failing since the last update.", "thumbs_up": 118, "review_created_version": "2.26.16.72", "at_utc": 1754870400.0, "at": "2026-08-11T00:00:00Z", "reply_author": "WhatsApp LLC", "reply_content": "Sorry about that — please contact us in-app so we can look into it.", "replied_utc": 1754884800.0, "replied_at": "2026-08-11T04:00:00Z" } ] } ``` Reviews are per-language: the `en` and `de` feeds for one app are different review sets, not translations of one set. # Get Similar Apps Source: https://docs.scrapebadger.com/api-reference/endpoint/google-play/get-similar GET https://scrapebadger.com/v1/google-play/apps/{app_id}/similar The apps Google Play recommends alongside a given app. The "Similar apps" rail from the app's detail page. Play caps that rail at roughly a dozen entries; the full list behind its "See more" link is a cluster page, addressable via `similar_apps_url` on the [detail response](/api-reference/endpoint/google-play/get-app). **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Android package id, e.g. `com.whatsapp`. ## Query Parameters Play storefront (`gl`) — recommendations are storefront-specific. Play content language (`hl`). ## Response The `app_id` the rail was read for. The Play URL the rail was read from. Apps returned. Recommended apps — same shape as [search results](/api-reference/endpoint/google-play/search). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google-play/apps/com.whatsapp/similar?country=US" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/google-play/apps/com.whatsapp/similar?country=US", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { apps } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/google-play/apps/com.whatsapp/similar", headers={"X-API-Key": "YOUR_API_KEY"}, params={"country": "US"}, ) apps = res.json()["apps"] ``` ```json Response theme={null} { "query": "com.whatsapp", "url": "https://play.google.com/store/apps/details?id=com.whatsapp&hl=en&gl=US", "result_count": 12, "apps": [ { "app_id": "org.telegram.messenger", "title": "Telegram", "developer": "Telegram FZ-LLC", "summary": "Fast. Secure. Powerful.", "icon": "https://play-lh.googleusercontent.com/telegram=w240-h480-rw", "score": 4.3, "score_text": "4.3", "installs": "1,000,000,000+", "genre": "Communication", "content_rating": "Everyone", "price": { "price": 0.0, "currency": "USD", "price_text": "Free", "is_free": true }, "url": "https://play.google.com/store/apps/details?id=org.telegram.messenger" } ] } ``` # List Categories Source: https://docs.scrapebadger.com/api-reference/endpoint/google-play/list-categories GET https://scrapebadger.com/v1/google-play/categories The Google Play app and game category ids. Free. Every Play app and game category id — the values [`/categories/{category_id}`](/api-reference/endpoint/google-play/browse-category) and `/collections/{collection}?category=` accept. They also match the `genre_id` returned on an app detail record. Static reference data, so this endpoint is **free**. **Credits:** 0 ## Authorization Your ScrapeBadger API key. ## Response Categories returned (60). e.g. `GAME_PUZZLE`. e.g. `Puzzle`. The Play category page. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google-play/categories" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch("https://scrapebadger.com/v1/google-play/categories", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY }, }); const { categories } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/google-play/categories", headers={"X-API-Key": "YOUR_API_KEY"}, ) categories = res.json()["categories"] ``` ```json Response theme={null} { "result_count": 60, "categories": [ { "category_id": "APPLICATION", "name": "All apps", "url": "https://play.google.com/store/apps/category/APPLICATION" }, { "category_id": "COMMUNICATION", "name": "Communication", "url": "https://play.google.com/store/apps/category/COMMUNICATION" }, { "category_id": "GAME", "name": "All games", "url": "https://play.google.com/store/apps/category/GAME" }, { "category_id": "GAME_PUZZLE", "name": "Puzzle", "url": "https://play.google.com/store/apps/category/GAME_PUZZLE" } ] } ``` The list covers the `APPLICATION` categories plus the `GAME_*` and `FAMILY_*` subcategories. # List Markets Source: https://docs.scrapebadger.com/api-reference/endpoint/google-play/list-markets GET https://scrapebadger.com/v1/google-play/markets Supported Google Play storefront countries (gl) and content languages (hl). Free. Supported storefront countries (`country` → Play's `gl`) and content languages (`lang` → Play's `hl`). Static reference data, so this endpoint is **free**. **Credits:** 0 Play is one global host, so the two axes are **independent**: `gl` selects pricing, availability and ranking; `hl` selects the language of descriptions and reviews. Every country is reachable from every other. ## Authorization Your ScrapeBadger API key. ## Response Storefront countries returned (47). Storefront countries. ISO 3166-1 alpha-2, e.g. `US`. e.g. `United States`. Content languages (31) — `code` is the `hl` value, e.g. `pt-BR`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google-play/markets" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch("https://scrapebadger.com/v1/google-play/markets", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY }, }); const { markets, languages } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/google-play/markets", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "result_count": 47, "markets": [ { "code": "US", "name": "United States" }, { "code": "GB", "name": "United Kingdom" }, { "code": "DE", "name": "Germany" }, { "code": "BR", "name": "Brazil" }, { "code": "JP", "name": "Japan" } ], "languages": [ { "code": "en", "name": "English" }, { "code": "de", "name": "German" }, { "code": "fr", "name": "French" }, { "code": "pt-BR", "name": "Portuguese (Brazil)" } ] } ``` # Search Apps Source: https://docs.scrapebadger.com/api-reference/endpoint/google-play/search GET https://scrapebadger.com/v1/google-play/search Search Google Play for apps and games — the rich result card carries description, installs, rating and price. Search Google Play for apps and games. Each result is a full `AppCard` — description, installs, rating, genre, content rating and price — so a search result rarely needs a follow-up detail fetch just to rank or filter. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `puzzle`. Play storefront (`gl`), ISO 3166-1 alpha-2. See [`/markets`](/api-reference/endpoint/google-play/list-markets). Play content language (`hl`), e.g. `en` or `pt-BR`. Restrict by price: `free` or `paid`. Omit for both. ## Response Echo of the requested query. The Play URL the results were read from. Apps returned. Matching apps, in Play's ranking order. Android package id, e.g. `com.king.candycrushsaga`. One-line pitch. Full store description, when the card carries it. Average rating, e.g. `4.6`. Rating as displayed, e.g. `4.6`. Install band, e.g. `1,000,000,000+`. `price`, `currency`, `price_text`, `is_free`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google-play/search?query=puzzle&country=US&price=free" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/google-play/search?" + new URLSearchParams({ query: "puzzle", country: "US", price: "free" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { apps } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/google-play/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "puzzle", "country": "US", "price": "free"}, ) apps = res.json()["apps"] ``` ```json Response theme={null} { "query": "puzzle", "url": "https://play.google.com/store/search?q=puzzle&c=apps&hl=en&gl=US&price=1", "result_count": 30, "apps": [ { "app_id": "com.king.candycrushsaga", "title": "Candy Crush Saga", "developer": "King", "summary": "Switch and match Candies in this tasty puzzle adventure", "icon": "https://play-lh.googleusercontent.com/example=w240-h480-rw", "header_image": "https://play-lh.googleusercontent.com/example=w720-h310-rw", "screenshots": ["https://play-lh.googleusercontent.com/shot1=w720"], "score": 4.6, "score_text": "4.6", "installs": "1,000,000,000+", "genre": "Casual", "content_rating": "Everyone", "price": { "price": 0.0, "currency": "USD", "price_text": "Free", "is_free": true }, "url": "https://play.google.com/store/apps/details?id=com.king.candycrushsaga" } ] } ``` ## Result depth Play server-renders about **30 results** per query and exposes no page number — its infinite-scroll continuation is a cluster RPC Google no longer accepts from outside its own client, so there is deliberately no `page` parameter. Widen a result set with [`/apps/{id}/similar`](/api-reference/endpoint/google-play/get-similar) and [`/developers/{id}`](/api-reference/endpoint/google-play/get-developer). Only the apps catalogue is searched. Play's books and movies catalogues use volume ids rather than Android package ids, so they are not returned here — their ids would 404 against every other route in this API. # Autocomplete Source: https://docs.scrapebadger.com/api-reference/endpoint/immobiliare/autocomplete GET /v1/immobiliare/autocomplete Resolve a free-text place into Immobiliare geography suggestions (region_id, province_id, city_id, macrozone_ids). Turn a free-text place into structured Immobiliare geography suggestions — nations, regions, provinces, cities (comuni) or zones. Use the returned `region_id` / `province_id` / `city_id` to drive precise [`/search`](/api-reference/endpoint/immobiliare/search) and [`/market-insights/prices`](/api-reference/endpoint/immobiliare/price-insights) queries. ## Query Parameters Partial location — city, province, region or zone, e.g. `Milano`. Market to search in. One of `it`, `es`, `gr`, `lu`. ## Response Geography suggestions, most relevant first. Id of the suggested geography entity. Human-readable label, e.g. `Milano`. One of `nation`, `region`, `province`, `comune`, `zone`. Region id — feed to `/search` and `/market-insights/prices`. Province id. City (comune) id. Macrozone ids when the suggestion is a `zone`. Search-results path on the market's portal. Echo of the requested market. ## Example ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/immobiliare/autocomplete?" + new URLSearchParams({ query: "Milano", market: "it" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/immobiliare/autocomplete", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "Milano", "market": "it"}, ) data = res.json() ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/immobiliare/autocomplete?query=Milano&market=it" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} { "suggestions": [ { "id": "8042", "label": "Milano", "type": "comune", "region_id": "10", "province_id": "MI", "city_id": "8042", "macrozone_ids": [], "url": "/vendita-case/milano/" }, { "id": "MI", "label": "Milano (provincia)", "type": "province", "region_id": "10", "province_id": "MI", "city_id": null, "macrozone_ids": [], "url": "/vendita-case/milano-provincia/" }, { "id": "10046", "label": "Navigli - Darsena, Milano", "type": "zone", "region_id": "10", "province_id": "MI", "city_id": "8042", "macrozone_ids": [10046], "url": "/vendita-case/milano/navigli/" } ], "market": "it" } ``` Each autocomplete request costs **2 credits**. Failed requests are not charged. # Get Agency Profile Source: https://docs.scrapebadger.com/api-reference/endpoint/immobiliare/get-agency GET /v1/immobiliare/agencies/{id} Full agency profile — address, GPS, phones, opening hours, ads / sales counts and the agent roster. Fetch a real-estate agency's full profile by its numeric id (from a listing's `agency.id` or its portal URL). Pair with [`/agencies/{id}/listings`](/api-reference/endpoint/immobiliare/get-agency-listings) to pull the agency's active inventory. ## Path Parameters Immobiliare agency id, e.g. `41235`. ## Query Parameters Market the agency belongs to. One of `it`, `es`, `gr`, `lu`. ## Response The full `AgencyProfile`: Agency id. e.g. `agency`, `builder`. Agency profile URL on the portal. Street address of the office. Agency self-description. Agency's own website. Agency logo URL. Paid portal customer. Franchise / network affiliation, e.g. `tecnocasa`. Active listings count. Completed sales count. Office phone numbers. Opening-hours lines. Agent roster. Agent photo URL. Echo of the requested market. ## Example ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/immobiliare/agencies/41235?market=it", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const agency = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/immobiliare/agencies/41235", headers={"X-API-Key": "YOUR_API_KEY"}, params={"market": "it"}, ) agency = res.json() ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/immobiliare/agencies/41235?market=it" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} { "id": 41235, "type": "agency", "name": "Tecnocasa Milano Crescenzago", "url": "https://www.immobiliare.it/agenzie-immobiliari/41235/tecnocasa-milano/", "address": "Via Padova 130, 20127 Milano", "description": "Affiliato Tecnocasa attivo dal 2003 nella zona Cimiano-Crescenzago. Compravendite e locazioni residenziali, valutazioni gratuite.", "website": "https://milano-crescenzago.tecnocasa.it", "image": "https://pic.im-cdn.it/agency/41235/large.png", "is_paid": true, "partnership": "tecnocasa", "real_estate_ads": 48, "real_estate_sales": 312, "region": "Lombardia", "province": "Milano", "city": "Milano", "macrozone": "Cimiano, Crescenzago, Adriano", "latitude": 45.498, "longitude": 9.2301, "phones": ["+39 02 2846120", "+39 02 2846121"], "opening_hours": [ "Mon-Fri 09:00-13:00, 14:30-19:00", "Sat 09:00-12:30" ], "agents": [ { "id": 998877, "name": "Marco", "surname": "Rossi", "gender": "male", "thumbnail": "https://pic.im-cdn.it/agent/998877/thumb.jpg" }, { "id": 998878, "name": "Giulia", "surname": "Bianchi", "gender": "female", "thumbnail": "https://pic.im-cdn.it/agent/998878/thumb.jpg" } ], "market": "it" } ``` Each agency-profile request costs **5 credits**. Failed requests are not charged. # Get Agency Listings Source: https://docs.scrapebadger.com/api-reference/endpoint/immobiliare/get-agency-listings GET /v1/immobiliare/agencies/{id}/listings Page through an agency's active listings — the same full Listing objects as /search. Fetch an agency's active listings, paginated. Each item is the same full `Listing` object returned by [`/search`](/api-reference/endpoint/immobiliare/search). ## Path Parameters Immobiliare agency id, e.g. `41235`. ## Query Parameters Market the agency belongs to. One of `it`, `es`, `gr`, `lu`. Contract type to list. One of `sale`, `rent`. Result page. ## Response Echo of the requested agency id. The agency's listings for this page. Immobiliare listing id — feed to [`/listings/{id}`](/api-reference/endpoint/immobiliare/get-listing). Stable listing UUID. Canonical listing URL on the market's portal. `sale` or `rent`. New construction. Luxury (LuxuryEstate) listing. Off-plan / development project. Multi-unit "mosaic" listing grouping several units. Paid visibility tier, e.g. `premium`, `top`, `star`. Property typology, e.g. `Apartment`, `Villa`. e.g. `residential`. `value`, `formatted`, `min_value`, `max_value`, `currency`, `visible`, `price_per_sqm`, `loan_from`. `address`, `latitude`, `longitude`, `region`, `province`, `city`, `macrozone`, `microzone`, `zipcode`, `nation_code`, `nation_name`. e.g. `85 m²`. `id`, `caption`, `small`, `medium`, `large`. `id`, `type`, `display_name`, `label`, `url`, `is_paid`, `guaranteed`, `show_logo`, `image_small`, `image_large`, `phones[]`. `type`, `display_name`, `label`, `image_gender`, `image_url`, `phones[]`. Number of units in this listing. Per-unit breakdown: `is_main`, `surface`, `surface_value`, `rooms`, `bathrooms`, `bedrooms`, `floor`, `elevator`, `garage`, `heating`, `energy_class`, `condominium_fees`, `typology`, `category`, `caption`, `description`, `price`, `features[{type,label,compact_label}]`, `ga4_features[]`, `views[]`, `photos[]`. When the listing was published. Last modification (UTC, ISO 8601). Last modification (portal-local formatting). All feature labels, flattened. Listings returned on this page. Echo of the requested page. Echo of the requested market. The full `Listing` field reference — including the nested `price`, `location`, `photos[]`, `agency`, `agent` and `properties[]` shapes — is documented on [`/search`](/api-reference/endpoint/immobiliare/search#response). ## Example ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/immobiliare/agencies/41235/listings?" + new URLSearchParams({ market: "it", page: "1" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/immobiliare/agencies/41235/listings", headers={"X-API-Key": "YOUR_API_KEY"}, params={"market": "it", "page": 1}, ) data = res.json() ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/immobiliare/agencies/41235/listings?market=it&page=1" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} { "agency_id": 41235, "listings": [ { "id": 121584766, "uuid": "c1f8a3f2-9a41-4a6e-bb3e-1e2f9d3a7c55", "url": "https://www.immobiliare.it/annunci/121584766/", "title": "Trilocale via Padova 120, Cimiano, Milano", "contract": "sale", "is_new": false, "luxury": false, "is_project": false, "is_mosaic": false, "visibility": "premium", "typology": "Apartment", "category": "residential", "price": { "value": 285000, "formatted": "€ 285.000", "min_value": null, "max_value": null, "currency": "EUR", "visible": true, "price_per_sqm": "3.353 €/m²", "loan_from": "€ 741/month" }, "location": { "address": "via Padova, 120", "latitude": 45.4972, "longitude": 9.2296, "region": "Lombardia", "province": "Milano", "city": "Milano", "macrozone": "Cimiano, Crescenzago, Adriano", "microzone": "Padova", "zipcode": "20127", "nation_code": "IT", "nation_name": "Italia" }, "surface": "85 m²", "rooms": "3", "bathrooms": "2", "floor": "3", "energy_class": "E", "description": "Luminoso trilocale al terzo piano con ascensore...", "photo_count": 24, "has_virtual_tour": true, "photos": [ { "id": 987654321, "caption": "soggiorno", "small": "https://pic.im-cdn.it/image/987654321/xsmall.jpg", "medium": "https://pic.im-cdn.it/image/987654321/medium.jpg", "large": "https://pic.im-cdn.it/image/987654321/large.jpg" } ], "agency": { "id": 41235, "type": "agency", "display_name": "Tecnocasa Milano Crescenzago", "label": "Tecnocasa", "url": "https://www.immobiliare.it/agenzie-immobiliari/41235/tecnocasa-milano/", "is_paid": true, "guaranteed": true, "show_logo": true, "image_small": "https://pic.im-cdn.it/agency/41235/small.png", "image_large": "https://pic.im-cdn.it/agency/41235/large.png", "phones": ["+39 02 2846120"] }, "agent": { "type": "agent", "display_name": "Marco Rossi", "label": "Agente", "image_gender": "male", "image_url": "https://pic.im-cdn.it/agent/998877/photo.jpg", "phones": ["+39 340 5512347"] }, "properties_count": 1, "properties": [ { "is_main": true, "surface": "85 m²", "surface_value": 85, "rooms": "3", "bathrooms": "2", "bedrooms": "2", "floor": "3° floor, with lift", "elevator": true, "garage": null, "heating": "Centralized, radiators, gas powered", "energy_class": "E", "condominium_fees": "€ 120/month", "typology": "Apartment", "category": "Residential", "caption": "Main unit", "description": "Luminoso trilocale al terzo piano con ascensore...", "price": "€ 285.000", "features": [ { "type": "balcony", "label": "Balcony", "compact_label": "Balcony" } ], "ga4_features": ["balcony", "cellar"], "views": [], "photos": [] } ], "creation_date": "2026-05-18", "last_modified_utc": "2026-07-02T09:14:05Z", "last_modified_at": "2026-07-02 11:14", "features_full": ["balcony", "cellar", "fitted wardrobes", "concierge"] } ], "count": 25, "page": 1, "market": "it" } ``` Each agency-listings request costs **5 credits**. Failed requests are not charged. # Get Listing Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/immobiliare/get-listing GET /v1/immobiliare/listings/{id} Full Immobiliare listing detail — price + €/m², surface, energy class, condo fees, GPS, all photos, per-unit breakdown, agency and agent contacts. Fetch a single listing's complete detail by its numeric id (from [`/search`](/api-reference/endpoint/immobiliare/search) or a portal URL such as `immobiliare.it/annunci/121584766/`). The response is the full `Listing` object — everything the search card has, plus the full description, all photos and the complete per-unit `properties[]` breakdown. ## Path Parameters Immobiliare listing id, e.g. `121584766`. ## Query Parameters Market the listing belongs to. One of `it`, `es`, `gr`, `lu`. ## Response The full `Listing`: Immobiliare listing id. Stable listing UUID. Canonical listing URL on the market's portal. `sale` or `rent`. New construction. Luxury (LuxuryEstate) listing. Off-plan / development project. Multi-unit "mosaic" listing grouping several units. Paid visibility tier, e.g. `premium`, `top`, `star`. Property typology, e.g. `Apartment`, `Villa`. e.g. `residential`. Price in EUR (null when hidden). e.g. `€ 285.000`. Range lower bound (project/mosaic listings). Range upper bound. Always `EUR`. `false` = price on request. e.g. `3.353 €/m²`. Estimated loan installment, e.g. `€ 741/month`. e.g. `IT`. e.g. `85 m²`. Full listing description. All listing photos. Small image URL. Medium image URL. Large image URL. Agency id — feed to [`/agencies/{id}`](/api-reference/endpoint/immobiliare/get-agency). e.g. `agency`, `builder`. Agency profile URL on the portal. Number of units in this listing. Per-unit breakdown (a plain listing has one main unit; projects/mosaics have several). e.g. `85 m²`. Numeric surface (m²). e.g. `3° floor, with lift`. e.g. `1 in garage/box`. e.g. `Centralized, radiators, gas powered`. e.g. `€ 120/month`. e.g. `balcony`. Machine-readable feature slugs. Views, e.g. `sea view`. Same shape as the listing-level `photos[]`. When the listing was published. Last modification (UTC, ISO 8601). Last modification (portal-local formatting). All feature labels, flattened. ## Example ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/immobiliare/listings/121584766?market=it", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const listing = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/immobiliare/listings/121584766", headers={"X-API-Key": "YOUR_API_KEY"}, params={"market": "it"}, ) listing = res.json() ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/immobiliare/listings/121584766?market=it" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} { "id": 121584766, "uuid": "c1f8a3f2-9a41-4a6e-bb3e-1e2f9d3a7c55", "url": "https://www.immobiliare.it/annunci/121584766/", "title": "Trilocale via Padova 120, Cimiano, Milano", "contract": "sale", "is_new": false, "luxury": false, "is_project": false, "is_mosaic": false, "visibility": "premium", "typology": "Apartment", "category": "residential", "price": { "value": 285000, "formatted": "€ 285.000", "min_value": null, "max_value": null, "currency": "EUR", "visible": true, "price_per_sqm": "3.353 €/m²", "loan_from": "€ 741/month" }, "location": { "address": "via Padova, 120", "latitude": 45.4972, "longitude": 9.2296, "region": "Lombardia", "province": "Milano", "city": "Milano", "macrozone": "Cimiano, Crescenzago, Adriano", "microzone": "Padova", "zipcode": "20127", "nation_code": "IT", "nation_name": "Italia" }, "surface": "85 m²", "rooms": "3", "bathrooms": "2", "floor": "3", "energy_class": "E", "description": "Luminoso trilocale al terzo piano con ascensore, doppia esposizione est/ovest, composto da soggiorno con balcone, cucina abitabile, due camere, doppi servizi e cantina. Riscaldamento centralizzato con contabilizzatori, portineria mezza giornata.", "photo_count": 24, "has_virtual_tour": true, "photos": [ { "id": 987654321, "caption": "soggiorno", "small": "https://pic.im-cdn.it/image/987654321/xsmall.jpg", "medium": "https://pic.im-cdn.it/image/987654321/medium.jpg", "large": "https://pic.im-cdn.it/image/987654321/large.jpg" }, { "id": 987654322, "caption": "cucina", "small": "https://pic.im-cdn.it/image/987654322/xsmall.jpg", "medium": "https://pic.im-cdn.it/image/987654322/medium.jpg", "large": "https://pic.im-cdn.it/image/987654322/large.jpg" } ], "agency": { "id": 41235, "type": "agency", "display_name": "Tecnocasa Milano Crescenzago", "label": "Tecnocasa", "url": "https://www.immobiliare.it/agenzie-immobiliari/41235/tecnocasa-milano/", "is_paid": true, "guaranteed": true, "show_logo": true, "image_small": "https://pic.im-cdn.it/agency/41235/small.png", "image_large": "https://pic.im-cdn.it/agency/41235/large.png", "phones": ["+39 02 2846120"] }, "agent": { "type": "agent", "display_name": "Marco Rossi", "label": "Agente", "image_gender": "male", "image_url": "https://pic.im-cdn.it/agent/998877/photo.jpg", "phones": ["+39 340 5512347"] }, "properties_count": 1, "properties": [ { "is_main": true, "surface": "85 m²", "surface_value": 85, "rooms": "3", "bathrooms": "2", "bedrooms": "2", "floor": "3° floor, with lift", "elevator": true, "garage": "1 in garage/box", "heating": "Centralized, radiators, gas powered", "energy_class": "E", "condominium_fees": "€ 120/month", "typology": "Apartment", "category": "Residential", "caption": "Main unit", "description": "Trilocale ristrutturato nel 2021...", "price": "€ 285.000", "features": [ { "type": "balcony", "label": "Balcony", "compact_label": "Balcony" }, { "type": "cellar", "label": "Cellar", "compact_label": "Cellar" }, { "type": "fitted_wardrobes", "label": "Fitted wardrobes", "compact_label": "Wardrobes" } ], "ga4_features": ["balcony", "cellar", "fitted_wardrobes", "external_exposure"], "views": [], "photos": [ { "id": 987654321, "caption": "soggiorno", "small": "https://pic.im-cdn.it/image/987654321/xsmall.jpg", "medium": "https://pic.im-cdn.it/image/987654321/medium.jpg", "large": "https://pic.im-cdn.it/image/987654321/large.jpg" } ] } ], "creation_date": "2026-05-18", "last_modified_utc": "2026-07-02T09:14:05Z", "last_modified_at": "2026-07-02 11:14", "features_full": ["balcony", "cellar", "fitted wardrobes", "concierge"] } ``` Each listing-detail request costs **10 credits**. Failed requests are not charged. # List Markets Source: https://docs.scrapebadger.com/api-reference/endpoint/immobiliare/list-markets GET /v1/immobiliare/markets List the four Immobiliare Group markets — Italy, Spain, Greece, Luxembourg. List the covered Immobiliare Group markets. All four portals share one platform, so every endpoint behaves identically across them — pass the market's `code` as the `market` parameter on any other endpoint. ## Response A JSON array of `Market` objects: Market code — pass as `market`, e.g. `it`. Portal domain, e.g. `www.immobiliare.it`. ISO country code, e.g. `IT`. Portal locale, e.g. `it`, `es`, `el`, `fr`. Always `EUR`. Human-readable market name. ## Example ```javascript Node.js theme={null} const res = await fetch("https://scrapebadger.com/v1/immobiliare/markets", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY }, }); const markets = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/immobiliare/markets", headers={"X-API-Key": "YOUR_API_KEY"}, ) markets = res.json() ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/immobiliare/markets" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} [ { "code": "it", "domain": "www.immobiliare.it", "country_code": "IT", "locale": "it", "currency": "EUR", "name": "Italy (Immobiliare.it)" }, { "code": "es", "domain": "www.indomio.es", "country_code": "ES", "locale": "es", "currency": "EUR", "name": "Spain (Indomio.es)" }, { "code": "gr", "domain": "www.indomio.gr", "country_code": "GR", "locale": "el", "currency": "EUR", "name": "Greece (Indomio.gr)" }, { "code": "lu", "domain": "www.immotop.lu", "country_code": "LU", "locale": "fr", "currency": "EUR", "name": "Luxembourg (Immotop.lu)" } ] ``` Listing markets is a **free** reference endpoint (0 credits). # Price Insights Source: https://docs.scrapebadger.com/api-reference/endpoint/immobiliare/price-insights GET /v1/immobiliare/market-insights/prices Monthly €/m² price-history time series for a region, province or city — sale or rent. Fetch the monthly **€/m²** price time series Immobiliare publishes for an area. Query at region, province or city granularity (most-specific id wins) and pick `sale` or `rent`. Get the geography ids from [`/autocomplete`](/api-reference/endpoint/immobiliare/autocomplete). ## Query Parameters Market. One of `it`, `es`, `gr`, `lu`. Region id (from `/autocomplete`). Province id — narrows the series to the province. City (comune) id — narrows the series to the city. Requires `province_id`. Price series to return. One of `sale`, `rent`. ## Response Echo of the requested contract (`sale` or `rent`). Always `EUR/m²`. Monthly time series, oldest first. Month, e.g. `2026-06`. Average price in EUR per m². Echo of the requested market. ## Example ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/immobiliare/market-insights/prices?" + new URLSearchParams({ market: "it", region_id: "10", province_id: "MI", city_id: "8042", contract: "sale", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/immobiliare/market-insights/prices", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "market": "it", "region_id": "10", "province_id": "MI", "city_id": "8042", "contract": "sale", }, ) data = res.json() ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/immobiliare/market-insights/prices?market=it®ion_id=10&province_id=MI&city_id=8042&contract=sale" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} { "contract": "sale", "unit": "EUR/m²", "points": [ { "label": "2025-08", "value": 5412 }, { "label": "2025-09", "value": 5438 }, { "label": "2025-10", "value": 5461 }, { "label": "2025-11", "value": 5449 }, { "label": "2025-12", "value": 5470 }, { "label": "2026-01", "value": 5492 }, { "label": "2026-02", "value": 5518 }, { "label": "2026-03", "value": 5544 }, { "label": "2026-04", "value": 5571 }, { "label": "2026-05", "value": 5590 }, { "label": "2026-06", "value": 5603 } ], "market": "it" } ``` Each price-insights request costs **10 credits**. Failed requests are not charged. # Search Listings Source: https://docs.scrapebadger.com/api-reference/endpoint/immobiliare/search GET /v1/immobiliare/search Search Immobiliare Group listings — sale / rent, all categories, with price, surface, rooms and bathrooms filters. Search a market's portal for listings. Target an area either with free-text `location` (auto-resolved via autocomplete) **or** with precise geography ids (`region_id` / `province_id` / `city_id`, e.g. from [`/autocomplete`](/api-reference/endpoint/immobiliare/autocomplete)). ## Query Parameters Market to search. One of `it`, `es`, `gr`, `lu`. Free-text place, auto-resolved to a geography — e.g. `Milano`, `Roma Trastevere`. Provide either `location` **or** the id parameters below. Region id (from `/autocomplete`). Alternative to `location`. Province id (from `/autocomplete`). City (comune) id (from `/autocomplete`). Contract type. One of `sale`, `rent`. Listing category. One of `residential`, `commercial`, `garages`, `offices`, `land`, `buildings`, `warehouses`. Minimum price (EUR). Maximum price (EUR). Minimum surface (m²). Maximum surface (m²). Minimum number of rooms. Maximum number of rooms. Minimum number of bathrooms. Sort order. One of `relevance`, `price_asc`, `price_desc`, `newest`, `oldest`, `surface_desc`, `surface_asc`. Result page. ## Response Listing cards for this page. Immobiliare listing id — feed to [`/listings/{id}`](/api-reference/endpoint/immobiliare/get-listing). Stable listing UUID. Canonical listing URL on the market's portal. `sale` or `rent`. New construction. Luxury (LuxuryEstate) listing. Off-plan / development project. Multi-unit "mosaic" listing grouping several units. Paid visibility tier, e.g. `premium`, `top`, `star`. Property typology, e.g. `Apartment`, `Villa`. e.g. `residential`. Price in EUR (null when hidden). e.g. `€ 285.000`. Range lower bound (project/mosaic listings). Range upper bound. Always `EUR`. `false` = price on request. e.g. `3.353 €/m²`. Estimated loan installment, e.g. `€ 741/month`. e.g. `IT`. e.g. `85 m²`. Small image URL. Medium image URL. Large image URL. Agency id — feed to [`/agencies/{id}`](/api-reference/endpoint/immobiliare/get-agency). e.g. `agency`, `builder`. Agency profile URL on the portal. Number of units in this listing. Per-unit breakdown (a plain listing has one main unit; projects/mosaics have several). e.g. `85 m²`. Numeric surface (m²). e.g. `3° floor, with lift`. e.g. `1 in garage/box`. e.g. `Centralized, radiators, gas powered`. e.g. `€ 120/month`. e.g. `balcony`. Machine-readable feature slugs. Views, e.g. `sea view`. Same shape as the listing-level `photos[]`. When the listing was published. Last modification (UTC, ISO 8601). Last modification (portal-local formatting). All feature labels, flattened. Listings returned on this page. Total matching listings. Last available page. `true` when the portal capped the result set — narrow the filters or split the area to get everything. Portal-suggested related searches for this area. Echo of the requested market. Portal domain the data came from, e.g. `www.immobiliare.it`. ## Example ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/immobiliare/search?" + new URLSearchParams({ location: "Milano", contract: "sale", category: "residential", price_max: "300000", rooms_min: "3", sort: "newest", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/immobiliare/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "location": "Milano", "contract": "sale", "category": "residential", "price_max": 300000, "rooms_min": 3, "sort": "newest", }, ) data = res.json() ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/immobiliare/search?location=Milano&contract=sale&category=residential&price_max=300000&rooms_min=3&sort=newest" \ -H "X-API-Key: YOUR_API_KEY" ``` ```json Response theme={null} { "listings": [ { "id": 121584766, "uuid": "c1f8a3f2-9a41-4a6e-bb3e-1e2f9d3a7c55", "url": "https://www.immobiliare.it/annunci/121584766/", "title": "Trilocale via Padova 120, Cimiano, Milano", "contract": "sale", "is_new": false, "luxury": false, "is_project": false, "is_mosaic": false, "visibility": "premium", "typology": "Apartment", "category": "residential", "price": { "value": 285000, "formatted": "€ 285.000", "min_value": null, "max_value": null, "currency": "EUR", "visible": true, "price_per_sqm": "3.353 €/m²", "loan_from": "€ 741/month" }, "location": { "address": "via Padova, 120", "latitude": 45.4972, "longitude": 9.2296, "region": "Lombardia", "province": "Milano", "city": "Milano", "macrozone": "Cimiano, Crescenzago, Adriano", "microzone": "Padova", "zipcode": "20127", "nation_code": "IT", "nation_name": "Italia" }, "surface": "85 m²", "rooms": "3", "bathrooms": "2", "floor": "3", "energy_class": "E", "description": "Luminoso trilocale al terzo piano con ascensore, doppia esposizione, balcone e cantina...", "photo_count": 24, "has_virtual_tour": true, "photos": [ { "id": 987654321, "caption": "soggiorno", "small": "https://pic.im-cdn.it/image/987654321/xsmall.jpg", "medium": "https://pic.im-cdn.it/image/987654321/medium.jpg", "large": "https://pic.im-cdn.it/image/987654321/large.jpg" } ], "agency": { "id": 41235, "type": "agency", "display_name": "Tecnocasa Milano Crescenzago", "label": "Tecnocasa", "url": "https://www.immobiliare.it/agenzie-immobiliari/41235/tecnocasa-milano/", "is_paid": true, "guaranteed": true, "show_logo": true, "image_small": "https://pic.im-cdn.it/agency/41235/small.png", "image_large": "https://pic.im-cdn.it/agency/41235/large.png", "phones": ["+39 02 2846120"] }, "agent": { "type": "agent", "display_name": "Marco Rossi", "label": "Agente", "image_gender": "male", "image_url": "https://pic.im-cdn.it/agent/998877/photo.jpg", "phones": ["+39 340 5512347"] }, "properties_count": 1, "properties": [ { "is_main": true, "surface": "85 m²", "surface_value": 85, "rooms": "3", "bathrooms": "2", "bedrooms": "2", "floor": "3° floor, with lift", "elevator": true, "garage": null, "heating": "Centralized, radiators, gas powered", "energy_class": "E", "condominium_fees": "€ 120/month", "typology": "Apartment", "category": "Residential", "caption": "Main unit", "description": "Luminoso trilocale al terzo piano con ascensore...", "price": "€ 285.000", "features": [ { "type": "balcony", "label": "Balcony", "compact_label": "Balcony" }, { "type": "cellar", "label": "Cellar", "compact_label": "Cellar" } ], "ga4_features": ["balcony", "cellar", "external_exposure"], "views": [], "photos": [] } ], "creation_date": "2026-05-18", "last_modified_utc": "2026-07-02T09:14:05Z", "last_modified_at": "2026-07-02 11:14", "features_full": ["balcony", "cellar", "fitted wardrobes", "concierge"] } ], "count": 25, "total_ads": 3417, "current_page": 1, "max_pages": 137, "is_results_limit_reached": false, "related_searches": [ { "label": "Case in vendita Sesto San Giovanni", "url": "/vendita-case/sesto-san-giovanni/" } ], "market": "it", "source": "www.immobiliare.it" } ``` Each search request costs **5 credits**. Failed requests are not charged. # Hashtag Info & Feeds Source: https://docs.scrapebadger.com/api-reference/endpoint/instagram/get-hashtag GET https://scrapebadger.com/v1/instagram/hashtags/{tag} Hashtag metadata by name, plus a paginated recent feed for the tag. Temporarily unavailable. **Temporarily unavailable.** This endpoint needs the authenticated Instagram tier, which is offline while we scale the account pool. Every call currently returns `503 {"error": "temporarily_unavailable"}` with a `Retry-After` header and is **not billed**. The public endpoints — [profile](/api-reference/endpoint/instagram/get-user), [posts](/api-reference/endpoint/instagram/user-posts), [media detail](/api-reference/endpoint/instagram/get-media) and [comments](/api-reference/endpoint/instagram/media-comments) — are live. Fetch a hashtag's metadata by `tag` (no `#`), then page its `recent` media feed. **Credits:** 5 (hashtag info) · 8 (`recent` feed) ## Authorization Your ScrapeBadger API key. ## Path Parameters Hashtag without the `#`, e.g. `travel`. ## Query Parameters (feed paths) Page size. Opaque next-page token from a previous `next_cursor`. ## Paths * `GET /v1/instagram/hashtags/{tag}` — hashtag info. **5 credits.** * `GET /v1/instagram/hashtags/{tag}/recent` — most recent media. **8 credits.** ## Response For the info path — a `Hashtag`: `id`, `name`, `media_count`, `profile_pic_url`. For feed paths — see the [Get Media](/api-reference/endpoint/instagram/get-media) field reference. Wrapped in `{ items, count, next_cursor, has_more }`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/instagram/hashtags/travel" \ -H "X-API-Key: YOUR_API_KEY" curl "https://scrapebadger.com/v1/instagram/hashtags/travel/recent?amount=20" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/instagram/hashtags/travel/recent?amount=20", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { items, next_cursor } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/instagram/hashtags/travel", headers={"X-API-Key": "YOUR_API_KEY"}, ) hashtag = res.json()["hashtag"] ``` ```json Response theme={null} { "hashtag": { "id": "17843712345678901", "name": "travel", "media_count": 712345678, "profile_pic_url": "https://scontent.cdninstagram.com/v/tag.jpg" } } ``` # Get Media Source: https://docs.scrapebadger.com/api-reference/endpoint/instagram/get-media GET https://scrapebadger.com/v1/instagram/media/{code} Full media detail by shortcode — photo, video, reel or carousel — with caption, counts, resources, usertags and location. Fetch a single piece of media by its shortcode `code` (the token in a `/p/…`, `/reel/…` or `/tv/…` URL). **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Media shortcode, e.g. `C8xYzAbCdE1`. ## Related paths * `GET /v1/instagram/media/{code}/oembed` — Instagram oEmbed payload. **Temporarily unavailable** — needs the authenticated tier, currently returns `503 temporarily_unavailable` (not billed). See the [overview](/instagram/overview). ## Response The full `Media`. Key fields: Shortcode. ISO 8601 UTC. Unix seconds. 1 = photo, 2 = video, 8 = carousel. e.g. `feed`, `clips` (reel), `igtv`, `carousel_container`. Author `UserShort`. Tagged users + position. Collab co-authors. `pk`, `name`, `lat`, `lng`. Carousel / multi-resource children. Parsed from the caption. Parsed from the caption. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/instagram/media/C8xYzAbCdE1" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/instagram/media/C8xYzAbCdE1", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { media } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/instagram/media/C8xYzAbCdE1", headers={"X-API-Key": "YOUR_API_KEY"}, ) media = res.json()["media"] ``` ```json Response theme={null} { "media": { "pk": "3401234567890123456", "id": "3401234567890123456_25025320", "code": "C8xYzAbCdE1", "taken_at": "2026-07-30T18:04:11Z", "taken_at_utc": 1785434651, "media_type": 2, "product_type": "clips", "caption_text": "Summer on Instagram. #summer @friend", "like_count": 1240553, "comment_count": 8842, "play_count": 9820114, "view_count": 9820114, "video_url": "https://scontent.cdninstagram.com/v/reel.mp4", "thumbnail_url": "https://scontent.cdninstagram.com/v/thumb.jpg", "url": "https://www.instagram.com/reel/C8xYzAbCdE1/", "user": { "pk": "25025320", "username": "instagram", "is_verified": true }, "usertags": [{ "user": { "username": "friend" }, "x": 0.5, "y": 0.5 }], "coauthor_producers": [], "location": { "pk": "213385402", "name": "New York, New York", "lat": 40.7128, "lng": -74.006 }, "resources": [], "hashtags": ["summer"], "mentions": ["friend"], "scraped_at": "2026-08-05T12:00:00Z" } } ``` # Get User Profile Source: https://docs.scrapebadger.com/api-reference/endpoint/instagram/get-user GET https://scrapebadger.com/v1/instagram/users/{username} Full public Instagram profile by username — bio, links, counts, verification and business metadata. Fetch a single public Instagram profile by its `username` (handle). **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Instagram handle without the `@`, e.g. `instagram`. ## Related paths * `GET /v1/instagram/users/{username}/related` — similar / suggested accounts. **Temporarily unavailable** — needs the authenticated tier, currently returns `503 temporarily_unavailable` (not billed). See the [overview](/instagram/overview). ## Response The full `User`. Key fields: Numeric account id. `title`, `url`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/instagram/users/instagram" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/instagram/users/instagram", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { user } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/instagram/users/instagram", headers={"X-API-Key": "YOUR_API_KEY"}, ) user = res.json()["user"] ``` ```json Response theme={null} { "user": { "pk": "25025320", "username": "instagram", "full_name": "Instagram", "is_private": false, "is_verified": true, "profile_pic_url": "https://scontent.cdninstagram.com/v/pfp.jpg", "profile_pic_url_hd": "https://scontent.cdninstagram.com/v/pfp_hd.jpg", "media_count": 8123, "follower_count": 682000000, "following_count": 245, "biography": "Discover what's next on Instagram.", "bio_links": [{ "title": "Help Center", "url": "https://help.instagram.com" }], "external_url": "https://about.instagram.com", "account_type": 3, "is_business": true, "public_email": null, "category": "Internet company", "city_name": "Menlo Park", "scraped_at": "2026-08-05T12:00:00Z" } } ``` # Comments Source: https://docs.scrapebadger.com/api-reference/endpoint/instagram/media-comments GET https://scrapebadger.com/v1/instagram/media/{code}/comments Paginated top-level comments on a media. Page through a media's top-level `comments`. **Credits:** 8 ## Authorization Your ScrapeBadger API key. ## Path Parameters Media shortcode. ## Query Parameters Page size. Opaque next-page token from a previous `next_cursor`. ## Paths * `GET /v1/instagram/media/{code}/comments` — top-level comments. * `GET /v1/instagram/media/{code}/comments/{comment_id}/likers` — likers of a comment. **Temporarily unavailable** — needs the authenticated tier, currently returns `503 temporarily_unavailable` (not billed). See the [overview](/instagram/overview). ## Response A `Comment`: `pk`, `text`, `user`, `created_at`, `created_at_utc`, `like_count`, `has_liked`. Null when exhausted. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/instagram/media/C8xYzAbCdE1/comments?amount=20" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/instagram/media/C8xYzAbCdE1/comments?amount=20", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { items, next_cursor } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/instagram/media/C8xYzAbCdE1/comments", headers={"X-API-Key": "YOUR_API_KEY"}, params={"amount": 20}, ) page = res.json() ``` ```json Response theme={null} { "items": [ { "pk": "17900000000000000", "text": "This is amazing!", "user": { "pk": "998877", "username": "fan_account", "is_verified": false }, "created_at": "2026-07-30T18:10:00Z", "created_at_utc": 1785434600, "like_count": 412, "has_liked": false } ], "count": 1, "next_cursor": "QVFE...==", "has_more": true } ``` # Search Source: https://docs.scrapebadger.com/api-reference/endpoint/instagram/search GET https://scrapebadger.com/v1/instagram/search/top Search Instagram across hashtags and blended top results. Temporarily unavailable. **Temporarily unavailable.** This endpoint needs the authenticated Instagram tier, which is offline while we scale the account pool. Every call currently returns `503 {"error": "temporarily_unavailable"}` with a `Retry-After` header and is **not billed**. The public endpoints — [profile](/api-reference/endpoint/instagram/get-user), [posts](/api-reference/endpoint/instagram/user-posts), [media detail](/api-reference/endpoint/instagram/get-media) and [comments](/api-reference/endpoint/instagram/media-comments) — are live. Search Instagram by keyword. Both typed endpoints share one query shape. **Credits:** 5 (`top`) · 2 (`hashtags`) ## Authorization Your ScrapeBadger API key. ## Query Parameters The search term. ## Paths * `GET /v1/instagram/search/hashtags` — matching hashtags (`Hashtag[]`). **2 credits.** * `GET /v1/instagram/search/top` — blended top results. **5 credits.** ## Response Typed results per path — `Hashtag` (hashtags) or a blended list (top). Wrapped in `{ items, count, next_cursor, has_more }`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/instagram/search/hashtags?query=travel" \ -H "X-API-Key: YOUR_API_KEY" curl "https://scrapebadger.com/v1/instagram/search/top?query=nasa" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/instagram/search/hashtags?" + new URLSearchParams({ query: "travel" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { items } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/instagram/search/hashtags", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "travel"}, ) items = res.json()["items"] ``` ```json Response theme={null} { "items": [ { "id": "17843712345678901", "name": "travel", "media_count": 712345678, "profile_pic_url": "https://scontent.cdninstagram.com/v/tag.jpg" } ], "count": 1, "next_cursor": null, "has_more": false } ``` # User Posts Source: https://docs.scrapebadger.com/api-reference/endpoint/instagram/user-posts GET https://scrapebadger.com/v1/instagram/users/{username}/posts Paginated posts for a user, wrapped in the standard list envelope. Page through a public user's `posts`. **Credits:** 8 per request ## Authorization Your ScrapeBadger API key. ## Path Parameters Instagram handle without the `@`. ## Query Parameters Page size — how many media items to return this page. Opaque next-page token from a previous response's `next_cursor`. Omit for the first page. ## Response Media cards — see the [Get Media](/api-reference/endpoint/instagram/get-media) field reference (`pk`, `id`, `code`, `taken_at`/`_utc`, `media_type`, `product_type`, `caption_text`, `like_count`, `comment_count`, `play_count`, `thumbnail_url`, `video_url`, `url`, `user`, `resources`, …). Items in this page. Pass back as `cursor` for the next page (null when exhausted). Whether more pages remain. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/instagram/users/instagram/posts?amount=12" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} let cursor, all = []; do { const res = await fetch( "https://scrapebadger.com/v1/instagram/users/instagram/posts?" + new URLSearchParams({ amount: "12", ...(cursor && { cursor }) }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const page = await res.json(); all.push(...page.items); cursor = page.has_more ? page.next_cursor : null; } while (cursor); ``` ```python Python theme={null} import requests cursor, items = None, [] while True: res = requests.get( "https://scrapebadger.com/v1/instagram/users/instagram/posts", headers={"X-API-Key": "YOUR_API_KEY"}, params={"amount": 12, **({"cursor": cursor} if cursor else {})}, ) page = res.json() items += page["items"] if not page["has_more"]: break cursor = page["next_cursor"] ``` ```json Response theme={null} { "items": [ { "pk": "3401234567890123456", "id": "3401234567890123456_25025320", "code": "C8xYzAbCdE1", "taken_at": "2026-07-30T18:04:11Z", "taken_at_utc": 1785434651, "media_type": 8, "product_type": "carousel_container", "caption_text": "Summer on Instagram.", "like_count": 1240553, "comment_count": 8842, "play_count": null, "thumbnail_url": "https://scontent.cdninstagram.com/v/thumb.jpg", "url": "https://www.instagram.com/p/C8xYzAbCdE1/" } ], "count": 1, "next_cursor": "QVFE...==", "has_more": true } ``` # Get Ad Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/leboncoin/get-ad GET /v1/leboncoin/ads/{list_id} Full detail for a single Leboncoin ad (price, attributes, images, location, seller, ...). ## Path Parameters The Leboncoin ad id (an integer). You can find this in search results or extract it from an ad URL (`/{slug}/{list_id}.htm`). ## Response Full ad object. Leboncoin ad id (integer). Ad title. Ad description text. Brand name, if detected (nullable). `offer` or `demand`. Full URL to the ad. Ad status (e.g. `active`). Leboncoin category id. Human-readable category name. Price in euros as an array (Leboncoin returns price as a list of integers). Price in cents (nullable). Price in euros as a number (nullable). Currency code. Always `EUR`. Raw first-publication date as shown on Leboncoin. ISO 8601 first-publication timestamp. Raw index (last-bumped) date. ISO 8601 index timestamp. Raw expiration date (nullable). ISO 8601 expiration timestamp (nullable). Whether the seller published a phone number. Number of times the ad was favorited (nullable). Image set for the ad. Total number of images. Standard-resolution image URLs. Thumbnail image URLs. Large / full-resolution image URLs. Category-specific attributes. Attribute machine key (e.g. `brand`). Human-readable attribute label (e.g. `Marque`). Attribute machine value. Human-readable attribute value. List of values for multi-value attributes (nullable). Whether the attribute is generic (shared across categories). Geographic location of the ad. Country id. Always `FR`. French region id (nullable). Region name (nullable). Department id (nullable). Department name (nullable). City machine name (nullable). City display name (nullable). Postal code (nullable). District / neighbourhood (nullable). Latitude (nullable). Longitude (nullable). Whether the location is an approximate shape rather than an exact point. Ad owner summary. Seller UUID. Store id, for pro sellers with a storefront (nullable). `private` or `pro`. Seller display name. SIREN company registration number, for pro sellers (nullable). Whether the seller opted out of solicitation. ### Example Response ```json theme={null} { "ad": { "list_id": 2845123456, "subject": "Vélo électrique VTC 500W - Excellent état", "body": "Vélo électrique acheté il y a 6 mois, très peu servi. Batterie 48V, autonomie 90 km.", "brand": "Moustache", "ad_type": "offer", "url": "https://www.leboncoin.fr/velos/2845123456.htm", "status": "active", "category_id": "24", "category_name": "Vélos", "price": [890], "price_cents": 89000, "price_eur": 890.0, "currency": "EUR", "first_publication_date": "2026-06-18 09:42:11", "first_publication_at": "2026-06-18T09:42:11Z", "index_date": "2026-06-20 14:10:03", "index_at": "2026-06-20T14:10:03Z", "expiration_date": "2026-08-17 09:42:11", "expiration_at": "2026-08-17T09:42:11Z", "has_phone": true, "favorites": 12, "images": { "nb_images": 3, "urls": ["https://img.leboncoin.fr/api/v1/lbcpb1/images/ab/cd/abcd.jpg"], "urls_thumb": ["https://img.leboncoin.fr/api/v1/lbcpb1/images/ab/cd/abcd_thumb.jpg"], "urls_large": ["https://img.leboncoin.fr/api/v1/lbcpb1/images/ab/cd/abcd_large.jpg"] }, "attributes": [ { "key": "brand", "key_label": "Marque", "value": "moustache", "value_label": "Moustache", "generic": true }, { "key": "condition", "key_label": "État", "value": "used", "value_label": "Très bon état", "generic": true } ], "location": { "country_id": "FR", "region_id": "22", "region_name": "Île-de-France", "department_id": "75", "department_name": "Paris", "city": "paris", "city_label": "Paris 11e", "zipcode": "75011", "lat": 48.8594, "lng": 2.3765, "is_shape": false }, "owner": { "user_id": "b3f1c2a0-8d4e-4a1b-9c2d-1e2f3a4b5c6d", "type": "private", "name": "Julien", "no_salesmen": true } } } ``` Each ad-detail request costs **5 credits**. Failed requests are not charged. # Get Seller Profile Source: https://docs.scrapebadger.com/api-reference/endpoint/leboncoin/get-seller GET /v1/leboncoin/sellers/{user_id} A Leboncoin seller's public profile, feedback summary, and store info. ## Path Parameters The Leboncoin seller id (a UUID). You can find this in the `owner.user_id` field of any ad. ## Response Seller profile object. Seller UUID. Store id, for pro sellers with a storefront (nullable). Seller display name. `private` or `pro`. ISO 8601 account creation timestamp (nullable). Number of active listings (nullable). Seller / store description (nullable). URL to the seller's profile picture (nullable). Seller location (nullable). List of badge strings awarded to the seller. Buyer feedback summary. Overall feedback score (nullable). Number of feedback entries received (nullable). Per-category score map (e.g. `{"communication": 4.8}`). Message reply rate (0-1 or percent, nullable). Seller presence status (e.g. `online`, nullable). SIREN company registration number, for pro sellers (nullable). SIRET establishment registration number, for pro sellers (nullable). Business activity sector, for pro sellers (nullable). Seller website URL (nullable). Average store rating (nullable). Total number of store ratings (nullable). Recent store reviews. Reviewer display name (nullable). Star rating for this review (nullable). Review body text (nullable). ISO 8601 review timestamp (nullable). ### Example Response ```json theme={null} { "seller": { "user_id": "b3f1c2a0-8d4e-4a1b-9c2d-1e2f3a4b5c6d", "store_id": "1029384756", "name": "Cycles Paris Pro", "account_type": "pro", "registered_at": "2019-04-12T00:00:00Z", "total_ads": 214, "description": "Vente de vélos neufs et d'occasion, réparation et entretien.", "profile_picture_url": "https://img.leboncoin.fr/api/v1/lbcpb1/images/pp/cyclesparis.jpg", "location": "Paris 11e (75011)", "badges": ["verified_id", "fast_reply"], "feedback": { "overall_score": 4.7, "received_count": 318, "category_scores": { "communication": 4.8, "shipping": 4.6, "conformity": 4.7 } }, "reply_rate": 0.96, "presence_status": "online", "siren": "812345678", "siret": "81234567800012", "activity_sector": "Commerce de détail de cycles", "website_url": "https://cyclesparispro.fr", "store_rating_value": 4.7, "store_ratings_total": 318, "store_reviews": [ { "author_name": "Marc D.", "rating_value": 5.0, "text": "Vélo conforme à la description, vendeur réactif.", "review_time": "2026-06-10T15:22:00Z" } ] } } ``` Each seller-profile request costs **5 credits**. Failed requests are not charged. # Get Seller Listings Source: https://docs.scrapebadger.com/api-reference/endpoint/leboncoin/get-seller-listings GET /v1/leboncoin/sellers/{user_id}/listings List the active ads of a single Leboncoin seller. ## Path Parameters The Leboncoin seller id (a UUID) whose active ads you want. ## Query Parameters Page number for paginated results. Results per page. Maximum `100`. ## Response The seller whose ads were returned. Array of the seller's active ads (same `Ad` shape as [search](/api-reference/endpoint/leboncoin/search-ads)). Leboncoin ad id (integer). Ad title. Ad description text. `offer` or `demand`. Full URL to the ad. Leboncoin category id. Human-readable category name. Price in euros as an array of integers. Price in euros as a number (nullable). Currency code. Always `EUR`. ISO 8601 first-publication timestamp. Image set with `nb_images`, `urls`, `urls_thumb`, `urls_large`. Location with `region_id`, `region_name`, `department_id`, `city_label`, `zipcode`, `lat`, `lng`. Owner summary with `user_id`, `type`, `name`. Total number of active ads for this seller. The page that was returned. The page size that was applied. ### Example Response ```json theme={null} { "user_id": "b3f1c2a0-8d4e-4a1b-9c2d-1e2f3a4b5c6d", "ads": [ { "list_id": 2845123456, "subject": "Vélo électrique VTC 500W - Excellent état", "body": "Vélo électrique acheté il y a 6 mois, très peu servi.", "ad_type": "offer", "url": "https://www.leboncoin.fr/velos/2845123456.htm", "category_id": "24", "category_name": "Vélos", "price": [890], "price_eur": 890.0, "currency": "EUR", "first_publication_at": "2026-06-18T09:42:11Z", "images": { "nb_images": 3, "urls": ["https://img.leboncoin.fr/api/v1/lbcpb1/images/ab/cd/abcd.jpg"], "urls_thumb": ["https://img.leboncoin.fr/api/v1/lbcpb1/images/ab/cd/abcd_thumb.jpg"], "urls_large": ["https://img.leboncoin.fr/api/v1/lbcpb1/images/ab/cd/abcd_large.jpg"] }, "location": { "region_id": "22", "region_name": "Île-de-France", "department_id": "75", "city_label": "Paris 11e", "zipcode": "75011", "lat": 48.8594, "lng": 2.3765 }, "owner": { "user_id": "b3f1c2a0-8d4e-4a1b-9c2d-1e2f3a4b5c6d", "type": "pro", "name": "Cycles Paris Pro" } } ], "total": 214, "page": 1, "limit": 35 } ``` Each seller-listings request costs **5 credits**. Failed requests are not charged. # Get Similar Ads Source: https://docs.scrapebadger.com/api-reference/endpoint/leboncoin/get-similar-ads GET /v1/leboncoin/ads/{list_id}/similar Ads similar to a given Leboncoin ad. ## Path Parameters The Leboncoin ad id (an integer) to find similar ads for. ## Query Parameters Maximum number of similar ads to return. Maximum `100`. ## Response The ad id the similar ads were requested for. Array of similar ads (same `Ad` shape as [search](/api-reference/endpoint/leboncoin/search-ads)). Leboncoin ad id (integer). Ad title. Ad description text. `offer` or `demand`. Full URL to the ad. Leboncoin category id. Human-readable category name. Price in euros as an array of integers. Price in euros as a number (nullable). Currency code. Always `EUR`. ISO 8601 first-publication timestamp. Image set with `nb_images`, `urls`, `urls_thumb`, `urls_large`. Location with `region_id`, `region_name`, `department_id`, `city_label`, `zipcode`, `lat`, `lng`. Owner summary with `user_id`, `type`, `name`. ### Example Response ```json theme={null} { "list_id": 2845123456, "ads": [ { "list_id": 2846987654, "subject": "Vélo électrique ville - Bon état", "body": "Vélo électrique urbain, batterie récente, freins à disque.", "ad_type": "offer", "url": "https://www.leboncoin.fr/velos/2846987654.htm", "category_id": "24", "category_name": "Vélos", "price": [750], "price_eur": 750.0, "currency": "EUR", "first_publication_at": "2026-06-19T11:05:00Z", "images": { "nb_images": 2, "urls": ["https://img.leboncoin.fr/api/v1/lbcpb1/images/ef/gh/efgh.jpg"], "urls_thumb": ["https://img.leboncoin.fr/api/v1/lbcpb1/images/ef/gh/efgh_thumb.jpg"], "urls_large": ["https://img.leboncoin.fr/api/v1/lbcpb1/images/ef/gh/efgh_large.jpg"] }, "location": { "region_id": "22", "region_name": "Île-de-France", "department_id": "92", "city_label": "Boulogne-Billancourt", "zipcode": "92100", "lat": 48.8355, "lng": 2.2404 }, "owner": { "user_id": "c4a2d3b1-9e5f-4b2c-8d3e-2f3a4b5c6d7e", "type": "private", "name": "Amélie" } } ] } ``` Each similar-ads request costs **5 credits**. Failed requests are not charged. # List Categories Source: https://docs.scrapebadger.com/api-reference/endpoint/leboncoin/list-categories GET /v1/leboncoin/categories List Leboncoin's categories and their ids. Returns the reference list of Leboncoin categories and their ids. Use a returned `id` with the [`category`](/api-reference/endpoint/leboncoin/search-ads) parameter on search. ## Response Array of categories. Leboncoin category id (e.g. `24`). Human-readable category name (e.g. `Vélos`). Parent category id, if nested (nullable). Parent category name, if nested (nullable). ### Example Response ```json theme={null} { "categories": [ { "id": "1", "name": "Véhicules", "parent_id": null, "parent_name": null }, { "id": "2", "name": "Voitures", "parent_id": "1", "parent_name": "Véhicules" }, { "id": "24", "name": "Vélos", "parent_id": "1", "parent_name": "Véhicules" }, { "id": "9", "name": "Immobilier", "parent_id": null, "parent_name": null } ] } ``` Listing categories is a **free** reference endpoint (0 credits). # List Departments Source: https://docs.scrapebadger.com/api-reference/endpoint/leboncoin/list-departments GET /v1/leboncoin/departments List Leboncoin's French departments, optionally filtered by region. Returns the reference list of French departments used by Leboncoin. Use a returned `id` with the [`department_id`](/api-reference/endpoint/leboncoin/search-ads) parameter on search. ## Query Parameters Restrict the list to departments within a single region. Use [`/v1/leboncoin/regions`](/api-reference/endpoint/leboncoin/list-regions) to look up region ids. Omit to return all departments. ## Response Array of departments. Leboncoin department id (e.g. `75`). Department name (e.g. `Paris`). The region this department belongs to. ### Example Response ```json theme={null} { "departments": [ { "id": "75", "name": "Paris", "region_id": "22" }, { "id": "77", "name": "Seine-et-Marne", "region_id": "22" }, { "id": "92", "name": "Hauts-de-Seine", "region_id": "22" }, { "id": "93", "name": "Seine-Saint-Denis", "region_id": "22" } ] } ``` Listing departments is a **free** reference endpoint (0 credits). # List Markets Source: https://docs.scrapebadger.com/api-reference/endpoint/leboncoin/list-markets GET /v1/leboncoin/markets List the supported Leboncoin markets with their domain, currency, and locale. Leboncoin is a single-country marketplace (France). This endpoint returns the market metadata programmatically for completeness and parity with other ScrapeBadger scrapers. ## Response Array of supported markets. Market code (e.g. `FR`). Leboncoin domain (e.g. `leboncoin.fr`). ISO 3166-1 alpha-2 country code. ISO 4217 currency code used in this market. BCP-47 locale (e.g. `fr-FR`). Marketplace country name. ### Example Response ```json theme={null} { "markets": [ { "code": "FR", "domain": "leboncoin.fr", "country": "FR", "currency": "EUR", "locale": "fr-FR", "name": "France" } ] } ``` Listing markets is a **free** reference endpoint (0 credits). # List Regions Source: https://docs.scrapebadger.com/api-reference/endpoint/leboncoin/list-regions GET /v1/leboncoin/regions List Leboncoin's French regions, including DOM-TOM overseas territories. Returns the reference list of French regions used by Leboncoin. Use a returned `id` with the [`region_id`](/api-reference/endpoint/leboncoin/search-ads) parameter on search. Overseas territories (DOM-TOM) are included as region values. ## Response Array of regions. Leboncoin region id (e.g. `22`). Region name (e.g. `Île-de-France`). ### Example Response ```json theme={null} { "regions": [ { "id": "22", "name": "Île-de-France" }, { "id": "20", "name": "Auvergne-Rhône-Alpes" }, { "id": "6", "name": "Provence-Alpes-Côte d'Azur" }, { "id": "26", "name": "Guadeloupe" }, { "id": "27", "name": "Martinique" }, { "id": "29", "name": "La Réunion" } ] } ``` Listing regions is a **free** reference endpoint (0 credits). # Search Ads Source: https://docs.scrapebadger.com/api-reference/endpoint/leboncoin/search-ads GET /v1/leboncoin/search Search Leboncoin classified ads across France with location, price, and seller filters. ## Query Parameters Search keywords. Matches against ad titles and descriptions. Restrict results to a Leboncoin category id. Use [`/v1/leboncoin/categories`](/api-reference/endpoint/leboncoin/list-categories) to look up ids. Restrict results to a French region (includes DOM-TOM overseas territories). Use [`/v1/leboncoin/regions`](/api-reference/endpoint/leboncoin/list-regions) to look up ids. Restrict results to a French department. Use [`/v1/leboncoin/departments`](/api-reference/endpoint/leboncoin/list-departments) to look up ids. Restrict results to a city name. Resolve names with [`/v1/leboncoin/locations/search`](/api-reference/endpoint/leboncoin/search-locations). Restrict results to a French postal code. Minimum price filter in euros. Maximum price filter in euros. Filter by seller type. | Value | Description | | - | - | | `all` | All sellers (default) | | `pro` | Professional sellers only | | `private` | Private individuals only | Filter by ad type. | Value | Description | | - | - | | `offer` | Items offered for sale (default) | | `demand` | Wanted / demand ads | Sort order for results. | Value | Description | | - | - | | `relevance` | Best match (default) | | `newest` | Most recently published first | | `oldest` | Oldest first | | `price_low` | Cheapest first | | `price_high` | Most expensive first | Page number for paginated results. Results per page. Maximum `100`. ## Response Array of matching ads. Leboncoin ad id (integer). Ad title. Ad description text. Brand name, if detected (nullable). `offer` or `demand`. Full URL to the ad. Ad status (e.g. `active`). Leboncoin category id. Human-readable category name. Price in euros as an array (Leboncoin returns price as a list of integers). Price in cents (nullable). Price in euros as a number (nullable). Currency code. Always `EUR`. Raw first-publication date as shown on Leboncoin. ISO 8601 first-publication timestamp. Raw index (last-bumped) date. ISO 8601 index timestamp. Raw expiration date (nullable). ISO 8601 expiration timestamp (nullable). Whether the seller published a phone number. Number of times the ad was favorited (nullable). Image set for the ad. Total number of images. Standard-resolution image URLs. Thumbnail image URLs. Large / full-resolution image URLs. Category-specific attributes. Attribute machine key (e.g. `brand`). Human-readable attribute label (e.g. `Marque`). Attribute machine value. Human-readable attribute value. List of values for multi-value attributes (nullable). Whether the attribute is generic (shared across categories). Geographic location of the ad. Country id. Always `FR`. French region id (nullable). Region name (nullable). Department id (nullable). Department name (nullable). City machine name (nullable). City display name (nullable). Postal code (nullable). District / neighbourhood (nullable). Latitude (nullable). Longitude (nullable). Whether the location is an approximate shape rather than an exact point. Ad owner summary. Seller UUID. Store id, for pro sellers with a storefront (nullable). `private` or `pro`. Seller display name. SIREN company registration number, for pro sellers (nullable). Whether the seller opted out of solicitation. Number of ads matching the current filters. Total ads matching the query across all seller types. Total matching ads from professional sellers. Total matching ads from private sellers. Total matching ads eligible for shipping. Maximum number of pages available for this query. The page that was returned. The page size that was applied. The upstream source the results were scraped from. ### Example Response ```json theme={null} { "ads": [ { "list_id": 2845123456, "subject": "Vélo électrique VTC 500W - Excellent état", "body": "Vélo électrique acheté il y a 6 mois, très peu servi. Batterie 48V.", "brand": "Moustache", "ad_type": "offer", "url": "https://www.leboncoin.fr/velos/2845123456.htm", "status": "active", "category_id": "24", "category_name": "Vélos", "price": [890], "price_cents": 89000, "price_eur": 890.0, "currency": "EUR", "first_publication_date": "2026-06-18 09:42:11", "first_publication_at": "2026-06-18T09:42:11Z", "index_date": "2026-06-20 14:10:03", "index_at": "2026-06-20T14:10:03Z", "expiration_date": "2026-08-17 09:42:11", "expiration_at": "2026-08-17T09:42:11Z", "has_phone": true, "favorites": 12, "images": { "nb_images": 3, "urls": ["https://img.leboncoin.fr/api/v1/lbcpb1/images/ab/cd/abcd.jpg"], "urls_thumb": ["https://img.leboncoin.fr/api/v1/lbcpb1/images/ab/cd/abcd_thumb.jpg"], "urls_large": ["https://img.leboncoin.fr/api/v1/lbcpb1/images/ab/cd/abcd_large.jpg"] }, "attributes": [ { "key": "brand", "key_label": "Marque", "value": "moustache", "value_label": "Moustache", "generic": true } ], "location": { "country_id": "FR", "region_id": "22", "region_name": "Île-de-France", "department_id": "75", "department_name": "Paris", "city": "paris", "city_label": "Paris 11e", "zipcode": "75011", "lat": 48.8594, "lng": 2.3765, "is_shape": false }, "owner": { "user_id": "b3f1c2a0-8d4e-4a1b-9c2d-1e2f3a4b5c6d", "type": "private", "name": "Julien", "no_salesmen": true } } ], "total": 1284, "total_all": 1284, "total_pro": 312, "total_private": 972, "total_shippable": 540, "max_pages": 37, "page": 1, "limit": 35, "source": "leboncoin.fr" } ``` Each search request costs **5 credits**. Failed requests are not charged. # Search Locations Source: https://docs.scrapebadger.com/api-reference/endpoint/leboncoin/search-locations GET /v1/leboncoin/locations/search Autocomplete a Leboncoin location by name, resolving it to region, department, and coordinates. Resolve a free-text place name (city, department, or region) into structured location suggestions you can use with the [`city`](/api-reference/endpoint/leboncoin/search-ads), `zipcode`, `region_id`, or `department_id` search parameters. ## Query Parameters The location name to autocomplete (e.g. `Lyon`). ## Response The location query that was executed. Array of matching location suggestions. Display label for the suggestion (e.g. `Lyon 69000`). City name (nullable). Postal code (nullable). French region id (nullable). Region name (nullable). Department id (nullable). Department name (nullable). Latitude (nullable). Longitude (nullable). Suggestion type: `city`, `department`, or `region`. ### Example Response ```json theme={null} { "query": "Lyon", "suggestions": [ { "label": "Lyon (69000)", "city": "Lyon", "zipcode": "69000", "region_id": "20", "region_name": "Auvergne-Rhône-Alpes", "department_id": "69", "department_name": "Rhône", "lat": 45.7578, "lng": 4.832, "type": "city" }, { "label": "Rhône (69)", "region_id": "20", "region_name": "Auvergne-Rhône-Alpes", "department_id": "69", "department_name": "Rhône", "type": "department" } ] } ``` Each location-search request costs **2 credits**. Failed requests are not charged. # Company Jobs Source: https://docs.scrapebadger.com/api-reference/endpoint/linkedin/company-jobs GET https://scrapebadger.com/v1/linkedin/companies/{company_id}/jobs Every public LinkedIn job opening for a company, by numeric company_id. List a company's public LinkedIn job openings by its numeric `company_id` (resolve a company name to its id with [`/geo/suggest`](/api-reference/endpoint/linkedin/geo-suggest) using `type=company`). Returns the same `JobCard` shape as [`/jobs/search`](/api-reference/endpoint/linkedin/search-jobs), paginated in blocks of 25 via `start`. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Numeric LinkedIn company id, e.g. `1035` (Microsoft). ## Query Parameters Pagination offset — `0`, `25`, `50`, … (page size is 25). Country/locale for the request. ## Response Result cards — same shape as job search: `job_id`, `title`, `job_url`, `company`, `company_url`, `company_logo`, `location`, `posted_at`, `posted_relative`, `is_new`, `benefits[]`. `result_count`, `start`, `has_more`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/linkedin/companies/1035/jobs" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/linkedin/companies/1035/jobs", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/linkedin/companies/1035/jobs", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "jobs": [ { "job_id": "3809988776", "title": "Software Engineer II", "job_url": "https://www.linkedin.com/jobs/view/3809988776", "company": "Microsoft", "company_url": "https://www.linkedin.com/company/microsoft", "company_logo": "https://media.licdn.com/dms/image/microsoft-logo.png", "location": "Redmond, WA", "posted_at": "2026-07-11T09:20:00Z", "posted_relative": "2 days ago", "is_new": true, "benefits": ["401(k)", "Medical insurance", "Vision insurance"] } ], "meta": { "result_count": 25, "start": 0, "has_more": true } } ``` # Geo / Company Suggest Source: https://docs.scrapebadger.com/api-reference/endpoint/linkedin/geo-suggest GET https://scrapebadger.com/v1/linkedin/geo/suggest Resolve a free-text place or company name to the numeric geo_id / company_id that job-search filters expect. Typeahead that turns a free-text place or company name into the numeric id LinkedIn's job filters use. Set `type=geo` to resolve a location to a `geo_id`, or `type=company` to resolve a company name to a `company_id`. Feed the returned id into [`/jobs/search`](/api-reference/endpoint/linkedin/search-jobs) (`geo_id` / `company_id`) or [`/companies/{company_id}/jobs`](/api-reference/endpoint/linkedin/company-jobs). **Credits:** 2 ## Authorization Your ScrapeBadger API key. ## Query Parameters Free-text place or company name, e.g. `London` or `Microsoft`. What to resolve — `geo` (locations) or `company` (companies). Country/locale for the request. ## Response Echo of the requested query. Echo of the requested type (`geo` or `company`). Suggestions. Numeric id — use as `geo_id` or `company_id`. Human-readable label. `geo` or `company`. ## Example ```bash cURL theme={null} # Resolve a location curl "https://scrapebadger.com/v1/linkedin/geo/suggest?query=London&type=geo" \ -H "X-API-Key: YOUR_API_KEY" # Resolve a company curl "https://scrapebadger.com/v1/linkedin/geo/suggest?query=Microsoft&type=company" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/linkedin/geo/suggest?" + new URLSearchParams({ query: "London", type: "geo" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/linkedin/geo/suggest", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "London", "type": "geo"}, ) data = res.json() ``` ```json Response theme={null} { "query": "London", "type": "geo", "suggestions": [ { "id": "102571732", "display_name": "London, England, United Kingdom", "type": "geo" } ] } ``` A `type=company` query for `Microsoft` returns `{ "id": "1035", "display_name": "Microsoft", "type": "company" }` — feed `1035` straight into [`/companies/1035/jobs`](/api-reference/endpoint/linkedin/company-jobs) or the `company_id` job-search filter. # Get Article Source: https://docs.scrapebadger.com/api-reference/endpoint/linkedin/get-article GET https://scrapebadger.com/v1/linkedin/articles/{article_slug} A public LinkedIn Pulse article by its slug — author, title, body, reactions and top-level comments. Fetch a public LinkedIn **Pulse** article by its `article_slug` (the `/pulse/` segment of the URL). Returns the same `Post` shape as [`/posts/{post_slug}`](/api-reference/endpoint/linkedin/get-post), with `type` set to `article` and the article headline in `title`. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Pulse article slug, e.g. `the-future-of-cloud-jane-smith`. ## Query Parameters Country/locale for the request. ## Response The `Post` (same shape as [`/posts`](/api-reference/endpoint/linkedin/get-post)). Always `article` here. The article headline. Article body text. Each: `author`, `author_url`, `text`, `published_at`, `like_count`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/linkedin/articles/the-future-of-cloud-jane-smith" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/linkedin/articles/the-future-of-cloud-jane-smith", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { post } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/linkedin/articles/the-future-of-cloud-jane-smith", headers={"X-API-Key": "YOUR_API_KEY"}, ) post = res.json()["post"] ``` ```json Response theme={null} { "post": { "post_id": "7209988776655443322", "url": "https://www.linkedin.com/pulse/the-future-of-cloud-jane-smith", "type": "article", "author_name": "Jane Smith", "author_url": "https://www.linkedin.com/in/jane-smith", "title": "The Future of Cloud Infrastructure", "text": "Over the last decade the cloud has moved from a cost-saving story to a platform for innovation…", "published_at": "2026-06-30T11:00:00Z", "like_count": 5400, "comment_count": 210, "comments": [ { "author": "Alex Kim", "author_url": "https://www.linkedin.com/in/alex-kim", "text": "Great overview — thanks for writing this up.", "published_at": "2026-06-30T12:15:00Z", "like_count": 32 } ] } } ``` # Get Company Source: https://docs.scrapebadger.com/api-reference/endpoint/linkedin/get-company GET https://scrapebadger.com/v1/linkedin/companies/{universal_name} A public LinkedIn company page by its universal_name slug — about, website, industry, size, headquarters, specialties and follower/employee counts. Fetch a company's public LinkedIn page by its `universal_name` slug (the `/company/` segment of the URL, e.g. `microsoft`). Returns the logged-out company card: about, website, industry, size, headquarters, specialties, and follower / employee counts. **Credits:** 6 ## Authorization Your ScrapeBadger API key. ## Path Parameters Company slug, e.g. `microsoft`. ## Query Parameters Country/locale for the request. ## Response The `Company`. e.g. `10,001+ employees`. e.g. `Public Company`. `street`, `city`, `region`, `postal_code`, `country`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/linkedin/companies/microsoft" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/linkedin/companies/microsoft", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { company } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/linkedin/companies/microsoft", headers={"X-API-Key": "YOUR_API_KEY"}, ) company = res.json()["company"] ``` ```json Response theme={null} { "company": { "universal_name": "microsoft", "linkedin_url": "https://www.linkedin.com/company/microsoft", "name": "Microsoft", "description": "Every person and every organization on the planet to achieve more.", "website": "https://news.microsoft.com/", "industry": "Software Development", "company_size": "10,001+ employees", "company_type": "Public Company", "headquarters": "Redmond, Washington", "founded": 1975, "specialties": ["Business Software", "Cloud Computing", "Developer Tools"], "employee_count": 238000, "follower_count": 24500000, "logo": "https://media.licdn.com/dms/image/microsoft-logo.png", "address": { "street": "1 Microsoft Way", "city": "Redmond", "region": "Washington", "postal_code": "98052", "country": "US" } } } ``` # Get Course Source: https://docs.scrapebadger.com/api-reference/endpoint/linkedin/get-course GET https://scrapebadger.com/v1/linkedin/learning/{course_slug} A LinkedIn Learning course by its slug — title, description, provider, workload, rating and instructors. Fetch a LinkedIn Learning course by its `course_slug` (the `/learning/` segment of the URL). Returns the course's title, description, provider, workload, rating and instructors. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Course slug, e.g. `learning-python`. ## Query Parameters Country/locale for the request. ## Response The `LearningCourse`. e.g. `2h 15m`. Each: `name`, `job_title`, `url`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/linkedin/learning/learning-python" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/linkedin/learning/learning-python", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { course } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/linkedin/learning/learning-python", headers={"X-API-Key": "YOUR_API_KEY"}, ) course = res.json()["course"] ``` ```json Response theme={null} { "course": { "slug": "learning-python", "url": "https://www.linkedin.com/learning/learning-python", "name": "Learning Python", "description": "Get started with Python, the popular general-purpose programming language.", "provider": "LinkedIn Learning", "workload": "2h 15m", "rating_value": 4.7, "rating_count": 18400, "instructors": [ { "name": "Joe Marini", "job_title": "Product & Engineering Leader", "url": "https://www.linkedin.com/in/joemarini" } ] } } ``` # Get Job Source: https://docs.scrapebadger.com/api-reference/endpoint/linkedin/get-job GET https://scrapebadger.com/v1/linkedin/jobs/{job_id} Full LinkedIn job detail by numeric job_id — description, salary, seniority, functions, industries, applicants and apply URL. Fetch a single LinkedIn job's complete detail by its numeric `job_id` (from [`/jobs/search`](/api-reference/endpoint/linkedin/search-jobs)). Extends the `JobCard` with the full description (HTML + text), salary, seniority, employment type, job functions, industries, applicant counts and the apply URL. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Numeric LinkedIn job id, e.g. `3801234567`. ## Query Parameters Country/locale for the request. ## Response The full `JobDetail`. Includes every `JobCard` field plus: Job description as sanitized HTML. Plain-text description. Advertised salary/range, when present. Human-readable applicant label, e.g. `Over 200 applicants`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/linkedin/jobs/3801234567" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/linkedin/jobs/3801234567", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { job } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/linkedin/jobs/3801234567", headers={"X-API-Key": "YOUR_API_KEY"}, ) job = res.json()["job"] ``` ```json Response theme={null} { "job": { "job_id": "3801234567", "title": "Senior Software Engineer", "job_url": "https://www.linkedin.com/jobs/view/3801234567", "company": "Acme Corp", "company_url": "https://www.linkedin.com/company/acme-corp", "company_logo": "https://media.licdn.com/dms/image/acme-logo.png", "location": "New York, NY", "posted_at": "2026-07-09T14:02:00Z", "posted_relative": "4 days ago", "is_new": false, "benefits": ["401(k)", "Medical insurance"], "description_html": "

We are looking for a Senior Software Engineer to join our platform team…

", "description_text": "We are looking for a Senior Software Engineer to join our platform team…", "salary": "$160,000 - $210,000", "seniority_level": "Mid-Senior level", "employment_type": "Full-time", "job_functions": ["Engineering", "Information Technology"], "industries": ["Software Development"], "applicants": "Over 200 applicants", "applicants_count": 214, "apply_url": "https://www.linkedin.com/jobs/view/3801234567/apply" } } ``` # Get Post Source: https://docs.scrapebadger.com/api-reference/endpoint/linkedin/get-post GET https://scrapebadger.com/v1/linkedin/posts/{post_slug} A public LinkedIn post by its slug — author, body, reactions and top-level comments. Fetch a public LinkedIn post by its `post_slug` (the activity slug from the post URL). Returns the author, body text, reaction and comment counts, and top-level comments. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Post slug, e.g. `activity-7212345678901234567`. ## Query Parameters Country/locale for the request. ## Response The `Post`. `social` for a feed post, `article` for a Pulse article. Present for articles; usually null for social posts. Each: `author`, `author_url`, `text`, `published_at`, `like_count`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/linkedin/posts/activity-7212345678901234567" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/linkedin/posts/activity-7212345678901234567", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { post } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/linkedin/posts/activity-7212345678901234567", headers={"X-API-Key": "YOUR_API_KEY"}, ) post = res.json()["post"] ``` ```json Response theme={null} { "post": { "post_id": "7212345678901234567", "url": "https://www.linkedin.com/posts/activity-7212345678901234567", "type": "social", "author_name": "Satya Nadella", "author_url": "https://www.linkedin.com/in/satyanadella", "title": null, "text": "Thrilled to share what our teams have been building this quarter…", "published_at": "2026-07-08T15:30:00Z", "like_count": 48200, "comment_count": 1320, "comments": [ { "author": "Jane Doe", "author_url": "https://www.linkedin.com/in/jane-doe", "text": "Congratulations to the whole team!", "published_at": "2026-07-08T16:02:00Z", "like_count": 84 } ] } } ``` # Get Profile Source: https://docs.scrapebadger.com/api-reference/endpoint/linkedin/get-profile GET https://scrapebadger.com/v1/linkedin/profiles/{public_id} A public LinkedIn member profile by vanity public_id — headline, location, about, experience, education, languages and awards. Fetch a member's public LinkedIn profile by their vanity `public_id` (the `/in/` segment of the URL, e.g. `williamhgates`). This is the **logged-out JSON-LD subset** LinkedIn exposes to signed-out visitors — **not** the full logged-in record. There is no contact info, no connection graph, and no full skills list. Experience and education are the coarse entries LinkedIn renders publicly. **Credits:** 8 ## Authorization Your ScrapeBadger API key. ## Path Parameters Member vanity slug, e.g. `williamhgates`. ## Query Parameters Country/locale for the request. ## Response The `Profile`. Each: `company`, `company_url`, `start_year`, `end_year`. Each: `school`, `school_url`, `start_year`, `end_year`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/linkedin/profiles/williamhgates" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/linkedin/profiles/williamhgates", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { profile } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/linkedin/profiles/williamhgates", headers={"X-API-Key": "YOUR_API_KEY"}, ) profile = res.json()["profile"] ``` ```json Response theme={null} { "profile": { "public_id": "williamhgates", "linkedin_url": "https://www.linkedin.com/in/williamhgates", "name": "Bill Gates", "headline": "Co-chair, Bill & Melinda Gates Foundation", "location": "Seattle, Washington, United States", "country": "US", "about": "Co-chair of the Bill & Melinda Gates Foundation. Founder of Breakthrough Energy. Co-founder of Microsoft.", "image": "https://media.licdn.com/dms/image/williamhgates.jpg", "follower_count": 36200000, "job_titles": ["Co-chair"], "current_company": "Bill & Melinda Gates Foundation", "current_company_url": "https://www.linkedin.com/company/bill-&-melinda-gates-foundation", "experience": [ { "company": "Bill & Melinda Gates Foundation", "company_url": "https://www.linkedin.com/company/bill-&-melinda-gates-foundation", "start_year": 2000, "end_year": null }, { "company": "Microsoft", "company_url": "https://www.linkedin.com/company/microsoft", "start_year": 1975, "end_year": 2020 } ], "education": [ { "school": "Harvard University", "school_url": "https://www.linkedin.com/school/harvard-university", "start_year": 1973, "end_year": 1975 } ], "languages": ["English"], "awards": [] } } ``` # Get School Source: https://docs.scrapebadger.com/api-reference/endpoint/linkedin/get-school GET https://scrapebadger.com/v1/linkedin/schools/{universal_name} A public LinkedIn university/school page by its universal_name slug — about, website, follower and student/alumni counts. Fetch a university or school's public LinkedIn page by its `universal_name` slug (the `/school/` segment of the URL, e.g. `stanford-university`). Returns the logged-out school card: about, website, follower count, and student/alumni count. **Credits:** 6 ## Authorization Your ScrapeBadger API key. ## Path Parameters School slug, e.g. `stanford-university`. ## Query Parameters Country/locale for the request. ## Response The `School`. `street`, `city`, `region`, `postal_code`, `country`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/linkedin/schools/stanford-university" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/linkedin/schools/stanford-university", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { school } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/linkedin/schools/stanford-university", headers={"X-API-Key": "YOUR_API_KEY"}, ) school = res.json()["school"] ``` ```json Response theme={null} { "school": { "universal_name": "stanford-university", "linkedin_url": "https://www.linkedin.com/school/stanford-university", "name": "Stanford University", "description": "Stanford University is one of the world's leading teaching and research institutions.", "website": "http://www.stanford.edu", "follower_count": 3120000, "student_alumni_count": 512000, "logo": "https://media.licdn.com/dms/image/stanford-logo.png", "address": { "street": "450 Serra Mall", "city": "Stanford", "region": "California", "postal_code": "94305", "country": "US" } } } ``` # Search Jobs Source: https://docs.scrapebadger.com/api-reference/endpoint/linkedin/search-jobs GET https://scrapebadger.com/v1/linkedin/jobs/search Search LinkedIn's public jobs guest API by keyword and location, with date, experience, job-type and workplace filters. Search `linkedin.com`'s public jobs surface by keyword and location, with filters for date posted, experience level, job type and workplace. Paginates in blocks of 25 via `start` (`0`, `25`, `50`). Returns lightweight `JobCard`s — hydrate a single card with [`/jobs/{job_id}`](/api-reference/endpoint/linkedin/get-job). **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Free-text query — e.g. `software engineer`. Free-text place — e.g. `New York`. Resolved server-side, or pass `geo_id` directly for an exact match. Numeric LinkedIn geo id (from [`/geo/suggest`](/api-reference/endpoint/linkedin/geo-suggest)). Overrides `location`. Restrict to a numeric company id. One of `past_24h`, `past_week`, `past_month`, `any` (default `any`). Experience level, CSV. One or more of `internship`, `entry`, `associate`, `mid_senior`, `director`, `executive`. Employment type, CSV. One or more of `full_time`, `part_time`, `contract`, `temporary`, `internship`, `volunteer`, `other`. Workplace, CSV. One or more of `onsite`, `remote`, `hybrid`. One of `relevant`, `recent`. Pagination offset — `0`, `25`, `50`, … (page size is 25). Country/locale for the request. ## Response Result cards. Each `JobCard` includes `job_id`, `title`, `job_url`, `company`, `company_url`, `company_logo`, `location`, `posted_at`, `posted_relative`, `is_new` and `benefits[]`. `result_count`, `start`, and `has_more` (whether another `start` page exists). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/linkedin/jobs/search?keywords=software%20engineer&location=New%20York&date_posted=past_week&workplace=remote,hybrid&sort=recent" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/linkedin/jobs/search?" + new URLSearchParams({ keywords: "software engineer", location: "New York", date_posted: "past_week", workplace: "remote,hybrid", sort: "recent", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/linkedin/jobs/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "keywords": "software engineer", "location": "New York", "date_posted": "past_week", "workplace": "remote,hybrid", "sort": "recent", }, ) data = res.json() ``` ```json Response theme={null} { "jobs": [ { "job_id": "3801234567", "title": "Senior Software Engineer", "job_url": "https://www.linkedin.com/jobs/view/3801234567", "company": "Acme Corp", "company_url": "https://www.linkedin.com/company/acme-corp", "company_logo": "https://media.licdn.com/dms/image/acme-logo.png", "location": "New York, NY", "posted_at": "2026-07-09T14:02:00Z", "posted_relative": "4 days ago", "is_new": false, "benefits": ["401(k)", "Medical insurance"] } ], "meta": { "result_count": 25, "start": 0, "has_more": true } } ``` `start` pages in increments of 25. Keep requesting the next page while `meta.has_more` is `true`. # Get List Details Source: https://docs.scrapebadger.com/api-reference/endpoint/lists/get-list-details get /v1/twitter/lists/{list_id}/detail Get detailed information about a Twitter list. Returns comprehensive list details including name, description, member count, subscriber count, visibility mode, and owner information. Useful for understanding list composition before fetching its tweets. # Get List Tweets Source: https://docs.scrapebadger.com/api-reference/endpoint/lists/get-list-tweets get /v1/twitter/lists/{list_id}/tweets Get tweets from a specific Twitter list. Returns comprehensive tweet data from the list's timeline including all metadata, media attachments, and engagement metrics. Supports pagination for lists with many tweets. # Search List Tweets Source: https://docs.scrapebadger.com/api-reference/endpoint/lists/search-list-tweets get /v1/twitter/lists/{list_id}/search_tweets Search for tweets within a specific Twitter list. Returns tweets from the list that match the given search query. Useful for finding specific content within curated tweet collections. # Get Broker Profile Source: https://docs.scrapebadger.com/api-reference/endpoint/loopnet/get-broker-profile GET /v1/loopnet/brokers/{slug}/{broker_id} Full LoopNet broker/professional profile — contact details, bio, specialties, and their listings. ## Path Parameters The broker's URL name slug, e.g. `john-smith`. Take it from the broker `url` field of a [search](/api-reference/endpoint/loopnet/search-listings) or [listing detail](/api-reference/endpoint/loopnet/get-listing-detail) result. The LoopNet broker id. Take it from the `broker_id` field of any listing's `brokers` array. ## Query Parameters Which market the broker profile lives in: `us` (loopnet.com), `ca` (loopnet.ca), `uk` (loopnet.co.uk), `fr` (loopnet.fr), or `es` (loopnet.es). ## Response The full `BrokerProfile` object. LoopNet broker id (nullable). Full name (nullable). Brokerage/company name (nullable). Job title (nullable). Phone number (nullable). Email (nullable). Headshot photo URL (nullable). Broker profile URL (nullable). Professional bio (nullable). Office street address (nullable). Office city (nullable). Office state/region (nullable). Real-estate license number (nullable). Specialty strings, e.g. `["Office", "Investment Sales"]`. Number of active listings (nullable). The broker's listings as `ListingCard` objects (see [Search Listings](/api-reference/endpoint/loopnet/search-listings)). Scrape time as a Unix timestamp (nullable). Scrape time as an ISO-8601 string (nullable). ### Example Response ```json theme={null} { "broker": { "broker_id": "w7x2k9d", "name": "John Smith", "company": "CBRE", "title": "Senior Vice President", "phone": "713-555-0100", "email": "john.smith@cbre.com", "photo": "https://images1.loopnet.com/i2/broker/photo.jpg", "url": "https://www.loopnet.com/commercial-real-estate-brokers/profile/john-smith/w7x2k9d/", "bio": "20+ years advising owners and occupiers on office leasing and investment sales across the Houston metro.", "address": "2800 Post Oak Blvd", "city": "Houston", "state": "TX", "license_number": "TX 0123456", "specialties": ["Office", "Investment Sales"], "listing_count": 14, "listings": [ { "position": 1, "listing_id": "12345678", "url": "https://www.loopnet.com/Listing/1000-Main-St-Houston-TX/12345678/", "listing_type": "for-lease", "property_type": "Office", "title": "1000 Main Street", "price_text": "$41.40 /SF/YR", "city": "Houston", "state": "TX" } ], "scraped_at": "2026-07-07T12:00:00Z" } } ``` Each broker-profile request costs **8 credits**. Failed requests are not charged. # Get Listing Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/loopnet/get-listing-detail GET /v1/loopnet/listings/{listing_id} Full detail for a single LoopNet listing — pricing, building facts, spaces, brokers, media, and the complete facts table. ## Path Parameters The LoopNet listing id. You can find this in search results (`listing_id`) or extract it from a listing URL. ## Query Parameters Which market the listing lives in: `us` (loopnet.com), `ca` (loopnet.ca), `uk` (loopnet.co.uk), `fr` (loopnet.fr), or `es` (loopnet.es). ## Response The full `ListingDetail` object. LoopNet listing id (nullable). LoopNet property id (nullable). Full URL to the listing (nullable). Market (`us`, `ca`, `uk`, `fr`, or `es`) (nullable). ISO country code (nullable). `for-lease`, `for-sale`, or `auction` (nullable). Transaction type as displayed, e.g. `For Lease`, `For Sale` (nullable). Property name (nullable). Listing headline (nullable). Listing subtitle (nullable). Full listing description (nullable). Bullet-point listing highlights. Price as displayed, e.g. `$41.40 /SF/YR`, `$2,500,000` (nullable). Parsed numeric price (nullable). ISO 4217 currency code (nullable). Rate period, e.g. `/SF/YR`; `null` for sale prices. Rental rate as displayed (nullable). Cap rate percentage (nullable). Net operating income as displayed (nullable). Price per square foot (nullable). Property type, e.g. `Office` (nullable). Property sub-type (nullable). Building class (`A`, `B`, `C`) (nullable). Building size in square feet (nullable). Building size as displayed (nullable). Rentable building area as displayed (nullable). Total space available as displayed (nullable). Total space available in square feet (nullable). Minimum divisible space (nullable). Maximum contiguous space (nullable). Typical floor size (nullable). Building height / number of stories as displayed (nullable). Clear ceiling height (nullable). Year built (nullable). Year built/renovated as displayed, e.g. `2003/2019` (nullable). LoopNet building star rating (nullable). Lot size as displayed (nullable). Lot size in acres (nullable). Number of units (multifamily) (nullable). Number of stories (nullable). Percent leased as displayed (nullable). Tenancy, e.g. `Multiple`, `Single` (nullable). Zoning designation (nullable). Parcel/APN id (nullable). Parking ratio / description (nullable). Walk Score (nullable). List of amenity strings. Street address (nullable). City (nullable). State/region (nullable). ZIP/postal code (nullable). County (nullable). Latitude (nullable). Longitude (nullable). Photo URLs. Total number of photos (nullable). Video URLs. Attached document (brochure/flyer) URLs. Whether a 3D virtual tour is available (nullable). Leasable spaces/units (lease listings). Space name, e.g. `2nd Floor, Ste 210` (nullable). Space use, e.g. `Office` (nullable). Space size in square feet (nullable). Size as displayed (nullable). Rent as displayed (nullable). Rent per square foot (nullable). Rent period: `/SF/YR`, `/SF/MO`, or `/MO` (nullable). Lease term (nullable). Space condition, e.g. `Full Build-Out` (nullable). Availability, e.g. `Now`, `Jan 2027` (nullable). Floor (nullable). Attributed brokers with `name`, `company`, `title`, `phone`, `email`, `photo`, `url`, `broker_id`, `city`, `region` (see the [Broker object](/api-reference/endpoint/loopnet/get-broker-profile)). Every LoopNet facts-table row, verbatim, as `{name, value}` pairs. Date posted as a Unix timestamp (nullable). Date posted as an ISO-8601 string (nullable). Last update as a Unix timestamp (nullable). Last update as an ISO-8601 string (nullable). Scrape time as a Unix timestamp (nullable). Scrape time as an ISO-8601 string (nullable). ### Example Response ```json theme={null} { "listing": { "listing_id": "12345678", "property_id": "87654321", "url": "https://www.loopnet.com/Listing/1000-Main-St-Houston-TX/12345678/", "market": "us", "country": "US", "listing_type": "for-lease", "transaction_type": "For Lease", "name": "1000 Main Street", "title": "1000 Main St, Houston, TX 77002", "subtitle": "Class A Office Tower", "description": "Trophy office tower in Houston's CBD with panoramic skyline views.", "highlights": ["On-site security", "Direct tunnel access", "Recently renovated lobby"], "price_text": "$41.40 /SF/YR", "price": 41.4, "price_currency": "USD", "price_period": "/SF/YR", "rental_rate_text": "$41.40 /SF/YR", "property_type": "Office", "building_class": "A", "building_size_sqft": 836000, "building_size_text": "836,000 SF", "total_space_available": "45,120 SF", "total_space_available_sqft": 45120, "typical_floor_size": "23,500 SF", "building_height": "36 Stories", "year_built": 2003, "year_built_renovated": "2003/2019", "building_rating": 4.5, "stories": 36, "percent_leased": "89%", "tenancy": "Multiple", "parking": "1.2/1,000 SF", "walk_score": 98, "amenities": ["Conference Rooms", "Fitness Center", "On-Site Security"], "address": "1000 Main St", "city": "Houston", "state": "TX", "zip": "77002", "county": "Harris", "latitude": 29.7539, "longitude": -95.3631, "images": ["https://images1.loopnet.com/i2/abc/116/photo-1.jpg"], "photo_count": 24, "has_virtual_tour": true, "spaces": [ { "name": "2nd Floor, Ste 210", "space_use": "Office", "size_sqft": 4500, "size_text": "4,500 SF", "rent_text": "$41.40 /SF/YR", "rent_per_sqft": 41.4, "rent_period": "/SF/YR", "term": "Negotiable", "condition": "Full Build-Out", "available_date": "Now", "floor": "2" } ], "brokers": [ { "name": "John Smith", "company": "CBRE", "title": "Senior Vice President", "phone": "713-555-0100", "broker_id": "w7x2k9d" } ], "additional_facts": [ { "name": "Building Class", "value": "A" }, { "name": "Parking Ratio", "value": "1.2/1,000 SF" } ], "date_updated_at": "2026-07-01T00:00:00Z", "scraped_at": "2026-07-07T12:00:00Z" } } ``` Each listing-detail request costs **12 credits**. Failed requests are not charged. # List Markets Source: https://docs.scrapebadger.com/api-reference/endpoint/loopnet/list-markets GET /v1/loopnet/markets List all supported LoopNet markets with their portals, currencies, and locales. ## Response Array of supported markets. Market code to use in the `market` query parameter (`us`, `ca`, `uk`, `fr`, or `es`). Portal domain (e.g. `www.loopnet.com`). ISO 3166-1 alpha-2 country code. ISO 4217 currency code used in this market. BCP-47 locale (e.g. `en-US`). Market country name. ### Example Response ```json theme={null} { "markets": [ { "code": "us", "domain": "www.loopnet.com", "country": "US", "currency": "USD", "locale": "en-US", "name": "United States" }, { "code": "ca", "domain": "www.loopnet.ca", "country": "CA", "currency": "CAD", "locale": "en-CA", "name": "Canada" }, { "code": "uk", "domain": "www.loopnet.co.uk", "country": "GB", "currency": "GBP", "locale": "en-GB", "name": "United Kingdom" }, { "code": "fr", "domain": "www.loopnet.fr", "country": "FR", "currency": "EUR", "locale": "fr-FR", "name": "France" }, { "code": "es", "domain": "www.loopnet.es", "country": "ES", "currency": "EUR", "locale": "es-ES", "name": "Spain" } ] } ``` Listing markets is a **free** reference endpoint (0 credits). # List Property Types Source: https://docs.scrapebadger.com/api-reference/endpoint/loopnet/list-property-types GET /v1/loopnet/property-types List all LoopNet property-type slugs accepted by the search `property_type` parameter. ## Response Array of supported property types. Slug to use in the search `property_type` query parameter (e.g. `office`). Human-readable name (e.g. `Office`). ### Example Response ```json theme={null} { "property_types": [ { "slug": "commercial-real-estate", "name": "All Commercial Real Estate" }, { "slug": "office", "name": "Office" }, { "slug": "office-buildings", "name": "Office Buildings" }, { "slug": "coworking", "name": "Coworking / Flexible Office" }, { "slug": "retail", "name": "Retail" }, { "slug": "restaurants", "name": "Restaurants" }, { "slug": "industrial", "name": "Industrial" }, { "slug": "warehouses", "name": "Warehouses" }, { "slug": "flex", "name": "Flex" }, { "slug": "apartment-buildings", "name": "Multifamily / Apartments" }, { "slug": "land", "name": "Land" }, { "slug": "hospitality", "name": "Hospitality / Hotel" }, { "slug": "health-care-facilities", "name": "Healthcare" }, { "slug": "specialty", "name": "Specialty" }, { "slug": "self-storage", "name": "Self-Storage" }, { "slug": "sports-and-entertainment", "name": "Sports & Entertainment" } ] } ``` Listing property types is a **free** reference endpoint (0 credits). # Search Listings Source: https://docs.scrapebadger.com/api-reference/endpoint/loopnet/search-listings GET /v1/loopnet/search Search a LoopNet market for commercial real-estate listings — for-lease, for-sale, or auctions. ## Query Parameters Free-text location: a city ("Houston, TX"), a ZIP code ("77002"), a state code ("TX"), or `usa` for the whole country. Which market to search: `us` (loopnet.com, USD), `ca` (loopnet.ca, CAD), `uk` (loopnet.co.uk, GBP), `fr` (loopnet.fr, EUR), or `es` (loopnet.es, EUR). Listing type filter. | Value | Description | | - | - | | `for-lease` | Space for lease (default) | | `for-sale` | Properties for sale | | `auctions` | Auction listings | Property-type slug, e.g. `office`, `retail`, `industrial`, `apartment-buildings`, `land`. Defaults to all commercial real estate. Use the [`/v1/loopnet/property-types`](/api-reference/endpoint/loopnet/list-property-types) endpoint for the full list. Page number for paginated results. Range: `1` - `20` (LoopNet caps results at roughly 500 per query, \~25 per page). Minimum price in the market's local currency. Maximum price in the market's local currency. How `min_price` / `max_price` are interpreted: `unit` (total price), `sf` (per square foot), or `acre` (per acre). Minimum size in square feet. Maximum size in square feet. ## Response The market that was searched (`us`, `ca`, `uk`, `fr`, or `es`). ISO 3166-1 alpha-2 country code for the market. ISO 4217 currency code for the market. The listing type that was searched (`for-lease`, `for-sale`, or `auctions`). The property-type slug that was searched (nullable). The location that was searched (nullable). Array of matching listing cards. 1-based position of the card in the results. LoopNet listing id (nullable). LoopNet property id (nullable). Full URL to the listing (nullable). `for-lease`, `for-sale`, or `auction` (nullable). Property type, e.g. `Office`, `Retail`, `Industrial` (nullable). LoopNet internal property-type id (nullable). Space use, e.g. `Office`, `Retail` (nullable). Listing status (nullable). LoopNet internal status id (nullable). LoopNet ad-exposure tier, e.g. `Diamond`, `Platinum` (nullable). Whether the listing is an auction (nullable). Branded name / headline (nullable). Card subtitle (nullable). Short card description (nullable). LoopNet building star rating, e.g. `4.0` (nullable). Year built (nullable). Price as displayed, e.g. `$41.40 /SF/YR`, `$2,500,000` (nullable). Parsed numeric price (nullable — CRE pricing is often "Contact broker"). ISO 4217 currency code (nullable). Rate period, e.g. `/SF/YR`, `/SF/MO`; `null` for sale prices. Size as displayed, e.g. `901 - 15,746 SF` (nullable). Minimum available size in square feet (nullable). Maximum available size in square feet (nullable). Street address (nullable). City (nullable). State/region (nullable). ZIP/postal code (nullable). County (nullable). ISO country code (nullable). LoopNet internal market id (nullable). Latitude (nullable). Longitude (nullable). Thumbnail photo URL (nullable). Whether a 3D virtual tour is available (nullable). LoopNet page rank of the card (nullable). LoopNet position rank of the card (nullable). Attributed brokers with `name`, `company`, `title`, `phone`, `email`, `photo`, `url`, `broker_id`, `city`, `region` (see the [Broker object](/api-reference/endpoint/loopnet/get-broker-profile)). Pagination info. Current page number. Results per page, typically \~25 (nullable). Total number of pages available (nullable). Total number of matching listings — LoopNet caps at \~500 (nullable). Scrape time as a Unix timestamp (nullable). Scrape time as an ISO-8601 string (nullable). ### Example Response ```json theme={null} { "market": "us", "country": "US", "currency": "USD", "listing_type": "for-sale", "property_type": "office", "location": "Houston, TX", "results": [ { "position": 1, "listing_id": "12345678", "property_id": "87654321", "url": "https://www.loopnet.com/Listing/1000-Main-St-Houston-TX/12345678/", "listing_type": "for-sale", "property_type": "Office", "space_use": "Office", "status": "Active", "exposure_level": "Diamond", "is_auction": false, "title": "1000 Main Street", "subtitle": "Class A Office Tower", "description": "Trophy office tower in Houston's CBD with panoramic skyline views.", "building_rating": 4.5, "year_built": 2003, "price_text": "$45,000,000", "price": 45000000, "price_currency": "USD", "price_period": null, "size_text": "836,000 SF", "size_min_sqft": 836000, "size_max_sqft": 836000, "address": "1000 Main St", "city": "Houston", "state": "TX", "zip": "77002", "county": "Harris", "country": "US", "latitude": 29.7539, "longitude": -95.3631, "thumbnail": "https://images1.loopnet.com/i2/abc/110/photo.jpg", "has_virtual_tour": true, "brokers": [ { "name": "John Smith", "company": "CBRE", "phone": "713-555-0100", "broker_id": "w7x2k9d" } ] } ], "pagination": { "current_page": 1, "per_page": 25, "total_pages": 12, "total_results": 288 }, "scraped_at": "2026-07-07T12:00:00Z" } ``` Each search request costs **10 credits**. Failed requests are not charged. # Autocomplete Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/autocomplete GET https://scrapebadger.com/v1/naver/autocomplete Get Naver search-box query suggestions for a partial term, each tagged with a type. Get Naver's search-box suggestions for a partial term. The cheapest call in this API — useful for expanding a seed keyword into real Naver queries before running [`/search`](/api-reference/endpoint/naver/search) on each one. Each suggestion is tagged with a `type` describing what kind of entity it points to. **Credits:** 1 ## Authorization Your ScrapeBadger API key. ## Query Parameters Partial search term, e.g. `제주`. ## Response Echo of the requested term. Number of suggestions. Suggested queries, in Naver's order. The suggested query text. The suggestion kind, e.g. `keyword`, `place`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/autocomplete?query=제주" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/autocomplete?" + new URLSearchParams({ query: "제주" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { suggestions } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/autocomplete", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "제주"}, ) suggestions = res.json()["suggestions"] ``` ```json Response theme={null} { "query": "제주", "result_count": 6, "suggestions": [ { "query": "제주도 맛집", "type": "keyword" }, { "query": "제주도 여행", "type": "keyword" }, { "query": "제주 날씨", "type": "keyword" }, { "query": "제주항공", "type": "keyword" }, { "query": "제주 렌트카", "type": "keyword" }, { "query": "제주도 가볼만한곳", "type": "keyword" } ] } ``` # Blog Search Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/blog GET https://scrapebadger.com/v1/naver/blog Search Naver Blog — title, blog name, author, snippet and absolute publish time per post, with thumbnail imagery. Search Naver Blog, the dominant consumer-review and how-to corpus in Korea. Each post carries the title, the blog it lives on, the author, a snippet and an **absolute publish time** (`published_at`), plus a thumbnail when one is shown. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `에어프라이어 추천`. 1-based result page for pagination. ## Response Echo of the requested query. The page that was fetched. Posts returned. Blog posts. 1-based rank. Destination post URL — any Naver redirect is resolved. The blog the post lives on. Post author / blogger handle. Raw publish date as displayed by Naver. ISO 8601 UTC publish time. Post thumbnail, when present. The Naver Blog SERP URL for this query and page. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/blog?query=에어프라이어+추천" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/blog?" + new URLSearchParams({ query: "에어프라이어 추천" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/blog", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "에어프라이어 추천"}, ) data = res.json() ``` ```json Response theme={null} { "query": "에어프라이어 추천", "page": 1, "result_count": 10, "results": [ { "position": 1, "title": "2026 에어프라이어 추천 TOP 5 솔직 후기", "url": "https://blog.naver.com/example/223456789012", "snippet": "직접 써본 에어프라이어 5종을 용량, 소비전력, 청소 편의성 기준으로 비교했습니다...", "blog_name": "살림꿀팁 블로그", "author": "살림꾼", "published": "2026.08.06.", "published_at": "2026-08-06T09:21:00+00:00", "thumbnail_url": "https://blogthumb.example.net/2026080612345.jpg" } ], "url": "https://search.naver.com/search.naver?where=blog&query=에어프라이어+추천" } ``` # Cafe Search Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/cafe GET https://scrapebadger.com/v1/naver/cafe Search the Naver Cafe vertical — community posts with cafe name, snippet, comment count and absolute publish times. Search the **Naver Cafe** vertical — posts from Naver's community forums. Each result carries the post title and URL, the hosting cafe's name and URL, a snippet, the comment count and an absolute publish timestamp. Returns 30 results per page. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords. 1-based result page. Each page returns 30 posts. ## Response Posts returned in this response. Cafe posts. 1-based rank within this page. Post URL. The hosting cafe's name. The hosting cafe's URL. Publish time as shown by Naver. Absolute publish timestamp (ISO 8601). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/cafe?query=캠핑+장비+추천&page=1" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/cafe?" + new URLSearchParams({"query": "캠핑 장비 추천", "page": "1"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/cafe", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "캠핑 장비 추천", "page": "1"}, ) data = res.json() ``` ```json Response theme={null} { "query": "캠핑 장비 추천", "page": 1, "result_count": 30, "results": [ { "position": 1, "title": "입문자용 캠핑 장비 추천 리스트", "url": "https://cafe.naver.com/camping/123456", "cafe_name": "캠핑러버", "cafe_url": "https://cafe.naver.com/camping", "snippet": "처음 캠핑 시작하시는 분들께...", "published": "2026.08.05.", "published_at": "2026-08-05T00:00:00+09:00", "comment_count": 42 } ] } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Clip Search Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/clip GET https://scrapebadger.com/v1/naver/clip Search the Naver Clip vertical — short-form vertical videos with author, view count and publish time. Search the **Naver Clip** vertical — Naver's short-form, vertical-video feed. Each result carries the clip title and URL, author, view count and an absolute publish timestamp. Returns 24 clips per page. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords. 1-based result page. Each page returns up to 24 clips. ## Response Clips. Clip URL. Absolute publish timestamp (ISO 8601). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/clip?query=홈카페+레시피&page=1" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/clip?" + new URLSearchParams({"query": "홈카페 레시피", "page": "1"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/clip", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "홈카페 레시피", "page": "1"}, ) data = res.json() ``` ```json Response theme={null} { "query": "홈카페 레시피", "page": 1, "result_count": 24, "results": [ { "position": 1, "title": "1분 홈카페 아인슈페너", "url": "https://m.clip.naver.com/clips/98765", "author": "카페인중독", "view_count": 120345, "published": "2026.07.11.", "published_at": "2026-07-11T00:00:00+09:00" } ] } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Get Group Review Summary Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/group-review-summary GET https://scrapebadger.com/v1/naver/product-groups/{group_product_no}/review-summary Group-level rating summary for a Naver storefront variant group — the combined score and review count across variants. Fetch the **group-level rating summary** for a storefront variant group — the combined average score and review count across all variants. Same shape as the per-product [`/products/{origin_product_no}/review-summary`](/api-reference/endpoint/naver/product-review-summary). **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters The variant group's product number (from [`/products/{origin_product_no}/group`](/api-reference/endpoint/naver/product-group)). ## Query Parameters Leaf category id for the group. ## Response ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/product-groups/G100200300/review-summary?leaf_category_id=50002345" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/product-groups/G100200300/review-summary?" + new URLSearchParams({"leaf_category_id": "50002345"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/product-groups/G100200300/review-summary", headers={"X-API-Key": "YOUR_API_KEY"}, params={"leaf_category_id": "50002345"}, ) data = res.json() ``` ```json Response theme={null} { "group_product_no": "G100200300", "leaf_category_id": "50002345", "review_count": 15320, "average_review_score": 4.7 } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Image Search Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/image GET https://scrapebadger.com/v1/naver/image Search the Naver image vertical — 100 images per page with thumbnail, full-resolution URL, dimensions and source. Search the **Naver image** vertical. Backed by Naver's image JSON API, it returns up to 100 images per page, each with its thumbnail and full-resolution URLs, dimensions, title and source site. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords. 1-based result page. Each page returns up to 100 images. ## Response Images. Naver image id. The page the image was found on. Source site name. Full-resolution image URL. Absolute publish timestamp (ISO 8601), when present. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/image?query=한라산+설경&page=1" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/image?" + new URLSearchParams({"query": "한라산 설경", "page": "1"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/image", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "한라산 설경", "page": "1"}, ) data = res.json() ``` ```json Response theme={null} { "query": "한라산 설경", "page": 1, "result_count": 100, "results": [ { "position": 1, "img_id": "blog_12345", "title": "한라산 겨울 설경", "url": "https://blog.example.com/hallasan", "source": "제주여행블로그", "thumbnail_url": "https://search-phinf.example.net/thumb/12345.jpg", "original_url": "https://blogfiles.example.net/hallasan_full.jpg", "width": 1920, "height": 1280 } ] } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Knowledge iN Search Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/kin GET https://scrapebadger.com/v1/naver/kin Search Naver Knowledge iN (지식iN) — community question-and-answer threads with the question, best answer and author. Search **Naver Knowledge iN** (`지식iN`), Korea's largest community Q\&A service. Each result carries the question title and URL, the question body, the accepted answer, the author and an absolute publish timestamp. Returns 10 results per page. **Credits:** 5 Knowledge iN exposes only the first page of results — the upstream “더보기” (load-more) control is JavaScript-driven and has no stable page cursor, so `page` above 1 returns the same first page. ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords. 1-based result page (see the note above). ## Response Knowledge iN threads. Thread URL. The question body. The accepted / top answer. Absolute publish timestamp (ISO 8601). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/kin?query=노트북+발열+해결&page=1" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/kin?" + new URLSearchParams({"query": "노트북 발열 해결", "page": "1"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/kin", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "노트북 발열 해결", "page": "1"}, ) data = res.json() ``` ```json Response theme={null} { "query": "노트북 발열 해결", "page": 1, "result_count": 10, "results": [ { "position": 1, "title": "노트북 발열 심한데 어떻게 하나요?", "url": "https://kin.naver.com/qna/detail.naver?d1id=1&dirId=1&docId=456789", "question": "게임만 하면 노트북이 너무 뜨거워요...", "answer": "쿨링패드 사용과 서멀구리스 재도포를 추천합니다...", "author": "컴닥터", "published": "2026.07.30.", "published_at": "2026-07-30T00:00:00+09:00" } ] } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Local Search Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/local GET https://scrapebadger.com/v1/naver/local Search Naver Place — local businesses with rating, review count, live opening status, category and addresses. Search Naver Place, Korea's dominant local-business directory. Each result carries the `place_id` (use it with [Place Detail](/api-reference/endpoint/naver/place) and [Place Reviews](/api-reference/endpoint/naver/place-reviews)), rating and review count, live opening status, category, both road and lot-number addresses, and any badges Naver attaches. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Place search keywords, e.g. `강남 파스타` or a business name. ## Response Echo of the requested query. Places returned. Local places. Naver Place id — use it with the detail and reviews endpoints. e.g. `파스타`, `카페`. Lot-number (jibun) address. Road-name (doro) address. Average visitor rating. Whether the place is open right now. Human-readable status, e.g. `영업 중`, `21:00에 영업 종료`. Labels Naver attaches, e.g. `예약`, `주차`. Naver Place page URL. 1-based rank within the results. The Naver Place search URL for this query. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/local?query=강남+파스타" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/local?" + new URLSearchParams({ query: "강남 파스타" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/local", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "강남 파스타"}, ) data = res.json() ``` ```json Response theme={null} { "query": "강남 파스타", "result_count": 10, "results": [ { "place_id": "1234567890", "name": "트라토리아 강남", "category": "파스타", "address": "서울특별시 강남구 역삼동 123-45", "road_address": "서울특별시 강남구 테헤란로 12길 34", "phone": "02-555-1234", "rating": 4.6, "review_count": 1823, "is_open": true, "open_status_text": "영업 중 · 22:00에 영업 종료", "badges": ["예약", "포장"], "url": "https://map.naver.com/p/entry/place/1234567890", "rank": 1 } ], "url": "https://map.naver.com/p/search/강남+파스타" } ``` # News Search Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/news GET https://scrapebadger.com/v1/naver/news Search Naver News — headline, source, snippet and absolute publish time per article, with thumbnail imagery. Search Naver News. Each article carries the headline, the publishing source, a snippet and an **absolute publish time** (`published_at`) alongside Naver's raw displayed date, plus a thumbnail when one is shown. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `금리 인상`. 1-based result page for pagination. ## Response Echo of the requested query. The page that was fetched. Articles returned. News articles. 1-based rank. Destination article URL — any Naver redirect is resolved. Publisher name. Raw publish date as displayed by Naver. ISO 8601 UTC publish time. Article thumbnail, when present. The Naver News SERP URL for this query and page. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/news?query=금리+인상" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/news?" + new URLSearchParams({ query: "금리 인상" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/news", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "금리 인상"}, ) data = res.json() ``` ```json Response theme={null} { "query": "금리 인상", "page": 1, "result_count": 10, "results": [ { "position": 1, "title": "한국은행, 기준금리 동결 결정", "url": "https://news.example.co.kr/article/2026080712345", "snippet": "한국은행 금융통화위원회는 기준금리를 현 수준에서 동결하기로 결정했다...", "source": "연합뉴스", "published": "2026.08.07.", "published_at": "2026-08-07T05:03:00+00:00", "thumbnail_url": "https://imgnews.example.co.kr/thumb/2026080712345.jpg" } ], "url": "https://search.naver.com/search.naver?where=news&query=금리+인상" } ``` # Get Place Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/place GET https://scrapebadger.com/v1/naver/place/{place_id} Full Naver Place detail — category, addresses, phone, website, rating, menus, photos and map coordinates. Fetch a single Naver Place by its `place_id`. Returns the full profile: the primary category and every category it is listed under, both road and lot-number addresses, phone, website, rating and review count, the menu with prices, photos, and the map coordinates. **Credits:** 8 This endpoint is **browser-rendered** — the richest and slowest call in this API, hence 8 credits. Take a `place_id` from a [`/local`](/api-reference/endpoint/naver/local) result or from the web SERP's `place_results[]`. ## Authorization Your ScrapeBadger API key. ## Path Parameters Naver Place id, e.g. `1234567890`. Take it from `place_id` on a [`/local`](/api-reference/endpoint/naver/local) result or from a `map.naver.com/p/entry/place/{place_id}` URL. ## Response Primary category, e.g. `파스타`. Every category the place is listed under. Lot-number (jibun) address. Road-name (doro) address. Average visitor rating. Menu items with prices. Price as displayed, e.g. `18,000원`. Photo URLs. Naver Place page URL. The underlying page the detail was rendered from. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/place/1234567890" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/place/1234567890", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const place = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/place/1234567890", headers={"X-API-Key": "YOUR_API_KEY"}, ) place = res.json() ``` ```json Response theme={null} { "place_id": "1234567890", "name": "트라토리아 강남", "category": "파스타", "categories": ["파스타", "이탈리아음식", "레스토랑"], "address": "서울특별시 강남구 역삼동 123-45", "road_address": "서울특별시 강남구 테헤란로 12길 34", "phone": "02-555-1234", "website": "https://trattoria-gangnam.example.com", "rating": 4.6, "review_count": 1823, "menus": [ { "name": "봉골레 파스타", "price": "18,000원" }, { "name": "트러플 크림 파스타", "price": "22,000원" } ], "images": [ "https://ldb-phinf.example.net/place/1234567890_1.jpg", "https://ldb-phinf.example.net/place/1234567890_2.jpg" ], "latitude": 37.500123, "longitude": 127.036456, "url": "https://map.naver.com/p/entry/place/1234567890", "source_url": "https://pcmap.place.naver.com/restaurant/1234567890/home" } ``` ## Errors | Status | Meaning | | - | - | | `404` | The place does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | # Get Place Photos Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/place-photos GET https://scrapebadger.com/v1/naver/place/{place_id}/photos Photo viewer for a Naver Place — visitor-review or owner photos with full-resolution URLs and cursor pagination. Fetch the photo stream for a single Naver Place. Choose between visitor-review photos and the owner/place photos. Each entry carries the full-resolution and thumbnail URLs, dimensions, a caption and a date. Results are cursor-paginated. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Naver Place id (digits), e.g. `1234567890`. Take it from a [`/local`](/api-reference/endpoint/naver/local) result. ## Query Parameters `placeReview` for visitor-review photos, or `biz` for the owner/place photos. Opaque pagination cursor. Pass the `next_cursor` from the previous response to fetch the next batch. ## Response Echo of the requested source. Photos returned in this batch. Photos (batch size varies, \~40–60). Full-resolution media URL. Caption, when present. Date as displayed. `image` or `video`. Rating from the attached review, when present. Cursor for the next batch, or `null` at the end. Whether another batch is available. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/place/1234567890/photos?media_source=placeReview" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/place/1234567890/photos?" + new URLSearchParams({"media_source": "placeReview"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/place/1234567890/photos", headers={"X-API-Key": "YOUR_API_KEY"}, params={"media_source": "placeReview"}, ) data = res.json() ``` ```json Response theme={null} { "place_id": "1234567890", "media_source": "placeReview", "result_count": 48, "photos": [ { "photo_id": "a1b2c3", "original_url": "https://pup-review-phinf.example.net/a1b2c3.jpg", "thumbnail_url": "https://pup-review-phinf.example.net/a1b2c3_t.jpg", "width": 1080, "height": 1080, "title": "봉골레 파스타", "date_text": "2026.07.02.", "media_format": "image", "media_source": "placeReview", "rating": 5 } ], "next_cursor": "eyJsYXN0Q3Vyc29yIjoiNDgifQ==", "has_next": true } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Get Place Reviews Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/place-reviews GET https://scrapebadger.com/v1/naver/place/{place_id}/reviews Visitor reviews for a Naver Place — rating, body, author, visit count, voted keywords and photos per review. Fetch the visitor review stream for a Naver Place. Each review carries its rating, body text, author, how many times they have visited, the voted keywords (Naver's structured "what was good" tags), any photos, and whether the owner has replied. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Naver Place id, e.g. `1234567890`. Take it from `place_id` on a [`/local`](/api-reference/endpoint/naver/local) result. ## Response Total reviews Naver reports for the place. Average visitor rating. Reviews returned in this response. Visitor reviews. Review text. How many times the author has visited. Where the review originated, e.g. a receipt- or booking-verified visit. Raw visit date as displayed by Naver. ISO 8601 UTC visit date. Naver's structured "what was good" tags, e.g. `음식이 맛있어요`. Photo URLs attached to the review. Whether the owner has replied. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/place/1234567890/reviews" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/place/1234567890/reviews", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/place/1234567890/reviews", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "place_id": "1234567890", "review_count": 1823, "rating": 4.6, "result_count": 10, "reviews": [ { "review_id": "5f3a9b2c7d1e", "rating": 5, "body": "봉골레 파스타가 정말 맛있었어요. 재방문 의사 100%입니다.", "author": "맛집탐험가", "visit_count": 3, "origin_type": "receipt", "visited": "2026.08.01.", "visited_at": "2026-08-01T00:00:00+00:00", "voted_keywords": ["음식이 맛있어요", "매장이 청결해요"], "images": ["https://pup-review.example.net/5f3a9b2c7d1e_1.jpg"], "has_reply": true } ] } ``` # Get Product Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/product-detail GET https://scrapebadger.com/v1/naver/products/{product_no} Full product detail for a Naver storefront product — price, options, delivery, seller, category and review stats. Fetch **full product detail** for a Naver storefront product by its channel product number. Returns the name, price and discount, rating and review count, brand and manufacturer, images, options, delivery, seller and category. **Credits:** 5 Brand Store products return the full record. For a SmartStore product, pass `store_url` or `channel_uid`; the response may be a partial enrichment, in which case `detail_source` is `smartstore_enrich` and `missing_fields[]` lists the fields that could not be filled. ## Authorization Your ScrapeBadger API key. ## Path Parameters Channel product number (the storefront `/products/{no}` id). ## Query Parameters `brand` or `smartstore`. Store slug. Required when `channel_uid` is omitted — resolves the channel and Referer. Opaque storefront channel key. Overrides store-home resolution. ## Response Purchasable option combinations. Delivery terms. Seller / channel summary. Category path. ISO registration time, when the full-detail schema is obtained. ISO last-modified time, when the full-detail schema is obtained. `smartstore_enrich` on a SmartStore partial record; omitted otherwise. Leaf field paths the partial lane could not fill; omitted otherwise. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/products/7001234567?host=brand&store_url=nike" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/products/7001234567?" + new URLSearchParams({"host": "brand", "store_url": "nike"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/products/7001234567", headers={"X-API-Key": "YOUR_API_KEY"}, params={"host": "brand", "store_url": "nike"}, ) data = res.json() ``` ```json Response theme={null} { "product_no": "7001234567", "name": "나이키 에어포스 1 '07", "price": 139000, "discount_price": 119000, "discount_rate": 14, "rating": 4.8, "review_count": 5231, "brand": "나이키", "manufacturer": "나이키", "images": [ "https://shop-phinf.example.net/7001234567_1.jpg" ], "options": [ { "name": "사이즈", "values": [ "250", "260", "270" ] } ], "delivery": { "fee": 0, "type": "오늘출발" }, "seller": { "channel_name": "나이키 공식스토어", "channel_uid": "2sV!nike01" }, "category": { "whole_category_name": "패션잡화>운동화" }, "registered_at": "2026-03-01T00:00:00+09:00", "modified_at": "2026-08-01T00:00:00+09:00" } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Get Product Group Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/product-group GET https://scrapebadger.com/v1/naver/products/{origin_product_no}/group The storefront variant group of a product — the group id and the member origin product numbers. Resolve the **variant group** a product belongs to. SmartStore sellers group colour/size variants under one group; this returns the group id and the member `originProductNo`s so you can fetch each variant. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters The product's origin product number. ## Response Echo of the requested product. The variant group id, or `null` when the product is not grouped. Member origin product numbers. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/products/5123456789/group" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/products/5123456789/group", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/products/5123456789/group", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "origin_product_no": "5123456789", "group_id": "G100200300", "origin_product_nos": [ "5123456789", "5123456790", "5123456791" ], "is_grouped": true } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # List Product Q&A Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/product-qna-list GET https://scrapebadger.com/v1/naver/products/{origin_product_no}/qnas Paginated product Q&A / inquiries for a Naver storefront product. List the **product Q\&A / inquiries** for a storefront product — shopper questions and the seller's answers, paginated. **Credits:** 5 Brand Store products are fully supported. SmartStore Q\&A requires `channel_uid` and may be unavailable. ## Authorization Your ScrapeBadger API key. ## Path Parameters The product's origin product number. ## Query Parameters Store/brand slug. Channel product number (the storefront `/products/{no}` id). `brand` or `smartstore`. Storefront channel uid; required for `host=smartstore`. 1-based page. ## Response Total Q\&A entries, when reported. Q\&A entries. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/products/5123456789/qnas?store_url=nike&product_no=7001234567&host=brand&page=1" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/products/5123456789/qnas?" + new URLSearchParams({"store_url": "nike", "product_no": "7001234567", "host": "brand", "page": "1"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/products/5123456789/qnas", headers={"X-API-Key": "YOUR_API_KEY"}, params={"store_url": "nike", "product_no": "7001234567", "host": "brand", "page": "1"}, ) data = res.json() ``` ```json Response theme={null} { "origin_product_no": "5123456789", "page": 1, "total_count": 128, "qnas": [ { "question": "275 사이즈 재입고 언제 되나요?", "answer": "다음 주 중 재입고 예정입니다.", "author_masked": "lee****", "created_at": "2026-07-20T00:00:00+09:00", "answered_at": "2026-07-21T00:00:00+09:00" } ] } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Get Product Review Summary Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/product-review-summary GET https://scrapebadger.com/v1/naver/products/{origin_product_no}/review-summary Rating summary for a Naver storefront product — average score, review count, star distribution and media/type counts. Fetch the **rating summary** for a storefront product — the average review score, total review count, the star distribution and the media/type breakdowns, without pulling the individual reviews. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters The product's origin product number. ## Query Parameters Leaf category id for the product. Optional — improves summary resolution when known. ## Response ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/products/5123456789/review-summary" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/products/5123456789/review-summary", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/products/5123456789/review-summary", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "origin_product_no": "5123456789", "leaf_category_id": "50002345", "review_count": 12043, "average_review_score": 4.8 } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # List Product Reviews Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/product-reviews-list GET https://scrapebadger.com/v1/naver/products/{origin_product_no}/reviews Paginated review list for a Naver storefront product, with sort control. List the **individual reviews** for a storefront product, paginated and sortable. Each review carries its rating, body, author (masked), options purchased and media. **Credits:** 5 Brand Store products are fully supported. SmartStore review listing requires a `checkout_merchant_no` and may be unavailable. ## Authorization Your ScrapeBadger API key. ## Path Parameters The product's origin product number. ## Query Parameters Store/brand slug. Channel product number (the storefront `/products/{no}` id, not the origin product number). `brand` or `smartstore`. SmartStore only — passed through when known. 1-based page. `REVIEW_RANKING` or `REVIEW_CREATE_DATE_DESC`. ## Response Total reviews, when reported. Reviews. The purchased option, when shown. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/products/5123456789/reviews?store_url=nike&product_no=7001234567&host=brand&page=1" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/products/5123456789/reviews?" + new URLSearchParams({"store_url": "nike", "product_no": "7001234567", "host": "brand", "page": "1"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/products/5123456789/reviews", headers={"X-API-Key": "YOUR_API_KEY"}, params={"store_url": "nike", "product_no": "7001234567", "host": "brand", "page": "1"}, ) data = res.json() ``` ```json Response theme={null} { "origin_product_no": "5123456789", "page": 1, "page_size": 20, "sort": "REVIEW_RANKING", "total_count": 5231, "reviews": [ { "review_id": "r900100", "rating": 5, "content": "사이즈 정사이즈이고 배송 빨라요", "author_masked": "kim****", "option": "270", "created_at": "2026-07-28T00:00:00+09:00", "images": [ "https://review-phinf.example.net/r900100.jpg" ] } ] } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Get Review Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/review-detail GET https://scrapebadger.com/v1/naver/reviews/{review_id} Commerce review detail by review id — fetch one or more Naver storefront reviews by their ids. Fetch **commerce review detail** by review id. Accepts one or more comma-separated ids and returns the full review objects, reporting any ids that could not be found. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters A review id, or several comma-separated ids. ## Response The ids requested. The resolved reviews. Requested ids that could not be resolved. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/reviews/r900100" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/reviews/r900100", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/reviews/r900100", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "requested_ids": [ "r900100" ], "reviews": [ { "review_id": "r900100", "rating": 5, "content": "사이즈 정사이즈이고 배송 빨라요", "author_masked": "kim****", "created_at": "2026-07-28T00:00:00+09:00", "images": [ "https://review-phinf.example.net/r900100.jpg" ] } ], "missing_ids": [] } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Get Review SSR Queries Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/review-ssr-queries GET https://scrapebadger.com/v1/naver/reviews/{review_id}/ssr-queries The server-rendered page query recipes for a review — a continuation helper that exposes the queries behind the review page. A **continuation helper** that returns the server-rendered page query recipes behind a review — the queries and variables the review page itself issues. Useful for advanced continuation and debugging. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters The review id. ## Response The review page the recipes were extracted from. The query recipes keyed by name. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/reviews/r900100/ssr-queries" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/reviews/r900100/ssr-queries", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/reviews/r900100/ssr-queries", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "review_id": "r900100", "source_url": "https://m.smartstore.naver.com/plusink/products/5123456789/reviews/r900100", "queries": { "getReviewDetail": { "variables": { "reviewId": "r900100" } } } } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Get Review Video Key Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/review-video-inkey GET https://scrapebadger.com/v1/naver/reviews/video-inkey Mint the video playback key (inKey) for a review-attached video from its attachVid and videoStamp. Mint the **video playback key** (`inKey`) for a video attached to a review. Pass the `attach_vid` and the `videoStamp` from the review's attachment and receive the video id and its playback key, which the player needs to stream the clip. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters The attached video id (`attachVid`). The `videoStamp` from the review attachment (type `M`). ## Response The playback key, or `null` when it could not be minted. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/reviews/video-inkey?attach_vid=A1B2C3D4&stamp=1699999999" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/reviews/video-inkey?" + new URLSearchParams({"attach_vid": "A1B2C3D4", "stamp": "1699999999"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/reviews/video-inkey", headers={"X-API-Key": "YOUR_API_KEY"}, params={"attach_vid": "A1B2C3D4", "stamp": "1699999999"}, ) data = res.json() ``` ```json Response theme={null} { "video_id": "A1B2C3D4", "in_key": "V_abcdef123456" } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Web Search Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/search GET https://scrapebadger.com/v1/naver/search Search the Naver web SERP — organic results, related searches and any local place pack, with resolved destination URLs. Search Naver's web SERP. Organic results carry the **resolved destination URL**, display URL, snippet and source. When Naver shows a local "place" block for the query, those entries are returned in `place_results[]`. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `제주도 맛집`. 1-based result page for pagination. ## Response Echo of the requested query. The page that was fetched. Organic results returned in this response. Organic results. 1-based rank within this page. Destination URL — any Naver redirect is resolved. Human-readable URL shown by Naver. Site or publisher name. Naver's related query suggestions, when present. The local "place" pack Naver shows for the query, when present — same shape as a [`/local`](/api-reference/endpoint/naver/local) result (`place_id`, `name`, `category`, `address`, `rating`, `review_count`, `url`, …). The Naver SERP URL for this query and page. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/search?query=제주도+맛집" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/search?" + new URLSearchParams({ query: "제주도 맛집" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "제주도 맛집"}, ) data = res.json() ``` ```json Response theme={null} { "query": "제주도 맛집", "page": 1, "result_count": 10, "results": [ { "position": 1, "title": "제주도 가볼 만한 맛집 BEST 20", "url": "https://blog.example.com/jeju-food", "display_url": "blog.example.com › jeju-food", "snippet": "제주 현지인이 추천하는 흑돼지, 고기국수, 해산물 맛집을 정리했습니다...", "source": "제주맛집블로그" } ], "related_searches": ["제주도 흑돼지 맛집", "제주 고기국수", "제주 애월 맛집"], "place_results": [ { "place_id": "1234567890", "name": "돈사돈", "category": "돼지고기구이", "address": "제주특별자치도 제주시 ...", "rating": 4.5, "review_count": 2841, "url": "https://map.naver.com/p/entry/place/1234567890", "rank": 1 } ], "url": "https://search.naver.com/search.naver?query=제주도+맛집" } ``` # Web Vertical Search Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/search-web GET https://scrapebadger.com/v1/naver/search/web Naver's dedicated web-document vertical SERP — 15 organic documents per page with resolved destination URLs. Search Naver's **web-document vertical** (the `웹사이트` tab). Unlike the integrated [`/search`](/api-reference/endpoint/naver/search) SERP, this is the pure web-document feed: 15 organic results per page, each with its resolved destination URL, display URL and snippet. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `제주도 맛집`. 1-based result page. Each page returns 15 documents. ## Response Echo of the requested query. The page that was fetched. Organic results returned in this response. Organic web documents. 1-based rank within this page. Destination URL — any Naver redirect is resolved. Human-readable URL shown by Naver. The Naver web-vertical SERP URL for this query and page. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/search/web?query=제주도+맛집&page=1" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/search/web?" + new URLSearchParams({"query": "제주도 맛집", "page": "1"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/search/web", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "제주도 맛집", "page": "1"}, ) data = res.json() ``` ```json Response theme={null} { "query": "제주도 맛집", "page": 1, "result_count": 15, "results": [ { "position": 1, "title": "제주도 맛집 추천 TOP 20", "url": "https://blog.example.com/jeju-food", "display_url": "blog.example.com › jeju-food", "snippet": "제주 현지인이 추천하는 흑돼지, 고기국수 맛집 정리..." } ], "url": "https://search.naver.com/search.naver?where=web&query=제주도+맛집" } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Shopping Bestsellers Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-bestsellers GET https://scrapebadger.com/v1/naver/shopping/bestsellers Naver Shopping bestseller product rankings by category, age bracket, sort metric and period. Fetch Naver Shopping's bestseller product rankings. Scope the chart by category, age bracket, the metric it is sorted by and the period. Each product carries its rank, the `nv_mid` catalogue id, title, price, discount, review score and count, mall name and imagery. **Credits:** 5 This endpoint returns Naver Shopping's **ranking data only**. General product search and SmartStore storefront listings are not offered. ## Authorization Your ScrapeBadger API key. ## Query Parameters Category to rank within. `ALL` for the overall chart, or a Naver Shopping category id. Age bracket to rank for. `ALL`, or a specific bracket. The metric the chart is sorted by, e.g. `PRODUCT_CLICK`. The ranking period, e.g. `DAILY`. ## Response Echo of the requested category. Echo of the requested age bracket. Echo of the requested sort metric. Echo of the requested period. When Naver last synced this ranking. Products returned. Ranked products. 1-based rank in the chart. Naver Shopping catalogue id. List price in KRW. Discounted price in KRW, when on offer. Discount percentage, when on offer. Average review score. The mall selling the product. Whether the entry is a sponsored placement. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/bestsellers?category_id=ALL&age_type=ALL&sort_type=PRODUCT_CLICK&period_type=DAILY" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/bestsellers?" + new URLSearchParams({ category_id: "ALL", age_type: "ALL", sort_type: "PRODUCT_CLICK", period_type: "DAILY", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/bestsellers", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "category_id": "ALL", "age_type": "ALL", "sort_type": "PRODUCT_CLICK", "period_type": "DAILY", }, ) data = res.json() ``` ```json Response theme={null} { "category_id": "ALL", "age_type": "ALL", "sort_type": "PRODUCT_CLICK", "period_type": "DAILY", "sync_date": "2026-08-07T00:00:00+00:00", "result_count": 100, "products": [ { "rank": 1, "nv_mid": "82613579214", "title": "삼성전자 갤럭시 버즈3 프로", "price": 279000, "discount_price": 229000, "discount_rate": 18, "review_score": 4.8, "review_count": 12043, "mall_name": "삼성전자 공식스토어", "product_url": "https://shopping.naver.com/catalog/82613579214", "image_url": "https://shopping-phinf.example.net/82613579214.jpg", "is_ad": false } ] } ``` # Shopping Brand Categories Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-brand-categories GET https://scrapebadger.com/v1/naver/shopping/brand-categories One level of the Naver Shopping brand-ranking category tree — DIV1 roots or the DIV2 children of a parent id. Walk the **brand-ranking category tree** that scopes [`/shopping/brand-rank`](/api-reference/endpoint/naver/shopping-brand-rank). With no `parent_id` it returns the DIV1 roots; pass an 8-digit `parent_id` to return its DIV2 children. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters An 8-digit DIV1 category id to list its DIV2 children. Omit for the roots. ## Response `DIV1` or `DIV2`. Echo of the requested parent, or `null` for roots. Categories at this level. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/brand-categories?parent_id=50000000" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/brand-categories?" + new URLSearchParams({"parent_id": "50000000"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/brand-categories", headers={"X-API-Key": "YOUR_API_KEY"}, params={"parent_id": "50000000"}, ) data = res.json() ``` ```json Response theme={null} { "depth": "DIV2", "parent_id": "50000000", "result_count": 9, "categories": [ { "category_id": "50000167", "category_name": "여성의류", "image_url": "https://shopping-phinf.example.net/brandcat/50000167.jpg" } ] } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Shopping Brand Rankings Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-brand-rank GET https://scrapebadger.com/v1/naver/shopping/brand-rank Naver Shopping brand ranking — the top 20 brands for a category, age bracket and period. Fetch Naver Shopping's **brand ranking** — the top 20 brands for a category, scoped by age bracket, sort metric and period. Each entry carries the brand's rank, name, logo, storefront URL and movement status. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters `A` for the overall chart, or an 8-digit brand-ranking category id. Age bracket, e.g. `ALL`, `MEN_20`, `WOMEN_30`. `BRAND_POPULAR` or `BRAND_ISSUE`. `WEEKLY` or `MONTHLY`. ## Response Brands returned (20). Ranked brands. Movement status versus the previous period. Absolute sync timestamp (ISO 8601). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/brand-rank?category_id=A&period_type=WEEKLY" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/brand-rank?" + new URLSearchParams({"category_id": "A", "period_type": "WEEKLY"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/brand-rank", headers={"X-API-Key": "YOUR_API_KEY"}, params={"category_id": "A", "period_type": "WEEKLY"}, ) data = res.json() ``` ```json Response theme={null} { "category_id": "A", "age_type": "ALL", "sort_type": "BRAND_POPULAR", "period_type": "WEEKLY", "result_count": 20, "brands": [ { "rank": 1, "rank_id": "b1", "title": "나이키", "status": "STABLE", "chart_type": "POPULAR", "tags": [ "스포츠" ], "brand_seq": "12345", "brand_channel_seq": "67890", "brand_name": "나이키", "brand_logo_url": "https://shopping-phinf.example.net/brand/12345.png", "brand_url": "https://brand.naver.com/nike", "sync_date": "2026-08-07", "synced_at": "2026-08-07T00:00:00+00:00" } ] } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Shopping Categories Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-categories GET https://scrapebadger.com/v1/naver/shopping/categories The static top-level Naver Shopping category taxonomy — 11 root category ids and names. Free. Return the **top-level Naver Shopping taxonomy** — the 11 root categories with their ids and names. Use the ids to scope the ranking, keyword and search endpoints. This is static reference data and is served free. **Credits:** 0 This endpoint is free (**0 credits**) — static public taxonomy, no upstream fetch. ## Authorization Your ScrapeBadger API key. ## Response Number of root categories (11). Root categories. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/categories" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/categories", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/categories", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "result_count": 11, "categories": [ { "category_id": "50000000", "name": "패션의류" }, { "category_id": "50000001", "name": "패션잡화" }, { "category_id": "50000002", "name": "화장품/미용" } ] } ``` # Shopping Category Tree Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-category-tree GET https://scrapebadger.com/v1/naver/shopping/category-tree One level of the Naver Shopping ranking category tree — DIV1 roots, or the DIV2 children of a parent id. Walk the **Naver Shopping ranking category tree** one level at a time. With no `parent_id` it returns the DIV1 root categories; pass a `parent_id` to return that node's DIV2 children. Each node carries its full ancestor id/name chain. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters A DIV1 category id to list its DIV2 children. Omit for the roots. ## Response Echo of the requested parent, or `null` for roots. The depth returned, e.g. `DIV1` or `DIV2`. Categories at this level. Ancestor category ids, root to leaf. Ancestor category names, root to leaf. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/category-tree?parent_id=50000000" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/category-tree?" + new URLSearchParams({"parent_id": "50000000"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/category-tree", headers={"X-API-Key": "YOUR_API_KEY"}, params={"parent_id": "50000000"}, ) data = res.json() ``` ```json Response theme={null} { "parent_id": "50000000", "level": "DIV2", "result_count": 12, "categories": [ { "type": "DIV2", "category_id": "50000167", "category_name": "원피스", "cat_id_1": "50000000", "cat_nm_1": "패션의류", "image_url": "https://shopping-phinf.example.net/cat/50000167.jpg" } ] } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Shopping Deals Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-deals GET https://scrapebadger.com/v1/naver/shopping/deals Curated Naver Shopping deal products, gender-scoped — a fixed 12-item best-deal card list. Fetch Naver Shopping's **curated deal products** (the `bestdeal` vertical). The list is gender-scoped and returns a fixed set of 12 deal cards, each with its rank, catalogue id, title, price, discount and labels. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters `M` or `F`. A blank gender returns an empty list upstream. ## Response Echo of the requested gender. Products returned (12). Curated deal products. Naver Shopping catalogue id. List price in KRW. Discounted price in KRW. Whether the item is a “찜” (wishlist) favourite. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/deals?gender=F" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/deals?" + new URLSearchParams({"gender": "F"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/deals", headers={"X-API-Key": "YOUR_API_KEY"}, params={"gender": "F"}, ) data = res.json() ``` ```json Response theme={null} { "gender": "F", "result_count": 12, "products": [ { "rank": 1, "nv_mid": "82613579214", "product_id": "5123456789", "channel_product_id": "7001234567", "title": "여성 여름 린넨 원피스", "image_url": "https://shopping-phinf.example.net/82613579214.jpg", "link_url": "https://shopping.naver.com/catalog/82613579214", "price": 39000, "price_value": 39000, "discount_price": 29900, "discount_rate": 23, "delivery_fee": 0, "labels": [ "무료배송", "오늘출발" ], "is_ad": false, "is_zzim": false } ] } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Shopping Insight Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-insight GET https://scrapebadger.com/v1/naver/shopping/insight Naver Shopping keyword insight — the ranked top search keywords for a category over a date range. Fetch Naver Shopping's keyword insight ranking — the top search keywords for a category over a date range. Use it to see what shoppers in a category are actually searching for. **Credits:** 5 This endpoint returns Naver Shopping's **ranking data only**. General product search and SmartStore storefront listings are not offered. ## Authorization Your ScrapeBadger API key. ## Query Parameters Naver Shopping category id to rank keywords within. Start of the date range, `YYYY-MM-DD`. End of the date range, `YYYY-MM-DD`. Aggregation unit, e.g. `date`, `week`, `month`. Number of keywords to return. ## Response Echo of the requested category. The date range the ranking covers. Keywords returned. Ranked keywords. 1-based rank. The search keyword. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/insight?category_id=50000000&start_date=2026-08-01&end_date=2026-08-07&time_unit=date&count=20" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/insight?" + new URLSearchParams({ category_id: "50000000", start_date: "2026-08-01", end_date: "2026-08-07", time_unit: "date", count: "20", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/insight", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "category_id": "50000000", "start_date": "2026-08-01", "end_date": "2026-08-07", "time_unit": "date", "count": 20, }, ) data = res.json() ``` ```json Response theme={null} { "category_id": "50000000", "date_range": "2026-08-01 ~ 2026-08-07", "result_count": 20, "keywords": [ { "rank": 1, "keyword": "반팔티" }, { "rank": 2, "keyword": "린넨 셔츠" }, { "rank": 3, "keyword": "샌들" } ] } ``` # Shopping IT Items Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-it-items GET https://scrapebadger.com/v1/naver/shopping/it-items Curated Naver Shopping “IT item” editorial cards — themed card lists each carrying a product set. Fetch Naver Shopping's **“IT item” editorial cards** — themed, curated card lists (e.g. trend and best-of round-ups). Each card carries its metadata and an embedded product set. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Response Cards returned. Editorial cards. Card metadata. Products featured on the card. The subset of cards flagged as best-of. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/it-items" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/it-items", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/it-items", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "result_count": 8, "cards": [ { "card_id": "it_001", "card_seq": 1, "card": { "gender": "F", "aggregate_type": "TREND", "text": "지금 뜨는", "title": "여름 홈웨어 베스트", "title_best": "여름 홈웨어", "exposure_rank": 1, "exposure_type": "MAIN", "img_url": "https://shopping-phinf.example.net/card/it_001.jpg", "active_start_ymd": "20260801", "sync_date": "2026-08-07T00:00:00+00:00" }, "products": [] } ], "best_cards": [] } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Shopping Keyword Periods Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-keyword-periods GET https://scrapebadger.com/v1/naver/shopping/keyword-periods The list of available periods for the Naver Shopping keyword ranking, for a category and age bracket. List the **available periods** for the Naver Shopping keyword ranking — the weeks or months you can request from [`/shopping/keywords`](/api-reference/endpoint/naver/shopping-keywords) for a given category and age bracket. The complete period list is returned in one response. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters `A`, or an 8-digit category id. Age bracket, e.g. `ALL`, `MEN_20`. Fixed at `KEYWORD_NEW`. `WEEKLY` or `MONTHLY`. ## Response Available periods. Period start date, `YYYYMMDD`. Period end date. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/keyword-periods?category_id=A&period_type=WEEKLY" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/keyword-periods?" + new URLSearchParams({"category_id": "A", "period_type": "WEEKLY"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/keyword-periods", headers={"X-API-Key": "YOUR_API_KEY"}, params={"category_id": "A", "period_type": "WEEKLY"}, ) data = res.json() ``` ```json Response theme={null} { "category_id": "A", "age_type": "ALL", "sort_type": "KEYWORD_NEW", "period_type": "WEEKLY", "result_count": 12, "periods": [ { "ymd": "20260804", "ended_at": "20260810", "month": 8, "week": 1, "period_type": "WEEKLY", "has_next": false, "has_prev": true } ] } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Shopping Keyword Rankings Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-keywords GET https://scrapebadger.com/v1/naver/shopping/keywords Trending Naver Shopping keyword rankings for a category, with rise/fall status and rank movement. Fetch Naver Shopping's **trending keyword ranking** for a category — the keywords shoppers are searching most, each with its rank, a sub-title, tags, a rise/fall status and the rank movement versus the previous period. **Credits:** 5 `category_id` is required and must be a real Naver Shopping category id — `ALL` returns an empty ranking. Take an id from [`/shopping/categories`](/api-reference/endpoint/naver/shopping-categories). ## Authorization Your ScrapeBadger API key. ## Query Parameters Category to rank within. A real category id — `ALL` returns empty. Age bracket to rank for. The metric the ranking is sorted by. `DAILY` or `WEEKLY`. ## Response Echo of the requested category. Ranked keywords. `RISE`, `FALL`, `STABLE`, `NEW`, `UP` or `DOWN`. Rank change versus the previous period. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/keywords?category_id=50000000&period_type=WEEKLY" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/keywords?" + new URLSearchParams({"category_id": "50000000", "period_type": "WEEKLY"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/keywords", headers={"X-API-Key": "YOUR_API_KEY"}, params={"category_id": "50000000", "period_type": "WEEKLY"}, ) data = res.json() ``` ```json Response theme={null} { "category_id": "50000000", "age_type": "ALL", "sort_type": "KEYWORD_POPULAR", "period_type": "WEEKLY", "result_count": 100, "keywords": [ { "rank": 1, "keyword": "여름 원피스", "sub_title": "", "tags": [ "여성의류" ], "status": "RISE", "rank_fluctuation": 3, "category_id": "50000167", "category_path": [ "패션의류", "여성의류", "원피스" ] } ] } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Get Live Broadcast Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-live-broadcast GET https://scrapebadger.com/v1/naver/shopping/live/broadcasts/{broadcast_id} Naver Shopping Live broadcast detail by id, including the embedded featured products. Fetch **Shopping Live broadcast detail** by id — the title, status and schedule, plus the featured products embedded in the broadcast. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Shopping Live broadcast id. ## Response Featured products on the broadcast. Broadcast detail. e.g. `ONAIR`, `END`, `STANDBY`. Scheduled start (KST). Scheduled start (UTC). Featured products. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/live/broadcasts/1234567" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/live/broadcasts/1234567", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/live/broadcasts/1234567", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "broadcast_id": "1234567", "item_count": 5, "source_url": "https://shoppinglive.naver.com/replays/1234567", "broadcast": { "title": "여름 침구 특가 라이브", "status": "END", "expectedStartDate": "2026-08-01T20:00:00+09:00", "expected_start_at": "2026-08-01T20:00:00+09:00", "expected_start_utc": "2026-08-01T11:00:00Z", "shoppingProducts": [ { "key": "p1", "name": "시원한 여름 이불", "salePrice": 59000, "discountedSalePrice": 39000 } ] } } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Get Live Broadcast Counts Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-live-broadcast-counts GET https://scrapebadger.com/v1/naver/shopping/live/broadcasts/{broadcast_id}/counts Viewer, like and comment counts for a Naver Shopping Live broadcast. Fetch the **engagement counts** for a Shopping Live broadcast — the viewer, like and comment totals. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Shopping Live broadcast id. ## Response Engagement counts. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/live/broadcasts/1234567/counts" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/live/broadcasts/1234567/counts", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/live/broadcasts/1234567/counts", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "broadcast_id": "1234567", "counts": { "viewerCount": 48213, "likeCount": 120345, "commentCount": 2841 } } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # List Live Broadcast Product Categories Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-live-broadcast-product-categories GET https://scrapebadger.com/v1/naver/shopping/live/broadcasts/{broadcast_id}/product-categories The product categories featured in a Naver Shopping Live broadcast. List the **product categories present in a Shopping Live broadcast** — the category chips shoppers can filter the broadcast's products by. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Shopping Live broadcast id. ## Query Parameters `MAIN` or `SUB`. ## Response Product categories. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/live/broadcasts/1234567/product-categories" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/live/broadcasts/1234567/product-categories", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/live/broadcasts/1234567/product-categories", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "broadcast_id": "1234567", "result_count": 3, "categories": [ { "id": "c1", "name": "침구" }, { "id": "c2", "name": "생활용품" } ] } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # List Live Broadcast Products Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-live-broadcast-products GET https://scrapebadger.com/v1/naver/shopping/live/broadcasts/{broadcast_id}/products Paginated product list for a single Naver Shopping Live broadcast. List the **products featured in a Shopping Live broadcast**, paginated. Each product carries its live price, discount and link. **Credits:** 5 `page` is 0-based. Omit it for the first page — `page=1` returns an empty list. ## Authorization Your ScrapeBadger API key. ## Path Parameters Shopping Live broadcast id. ## Query Parameters 0-based page. Omit for the first page. Products per page (1–200). Omit for the upstream default. ## Response Live products. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/live/broadcasts/1234567/products?size=20" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/live/broadcasts/1234567/products?" + new URLSearchParams({"size": "20"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/live/broadcasts/1234567/products", headers={"X-API-Key": "YOUR_API_KEY"}, params={"size": "20"}, ) data = res.json() ``` ```json Response theme={null} { "broadcast_id": "1234567", "page": 0, "total_count": 5, "total_page": 1, "result_count": 5, "products": [ { "key": "p1", "name": "시원한 여름 이불", "salePrice": 59000, "discountedSalePrice": 39000, "productUrl": "https://shopping.naver.com/catalog/82614111000", "imageUrl": "https://shop-phinf.example.net/p1.jpg" } ] } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Get Live Channel Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-live-channel GET https://scrapebadger.com/v1/naver/shopping/live/channels/{channel_id} Naver Shopping Live channel / store profile — nickname, on-air status and scheduled broadcasts. Fetch a **Shopping Live channel (store) profile** — the channel nickname, current on-air status and any scheduled upcoming broadcast. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Shopping Live channel id. ## Response Channel profile. Whether the channel is live now. Next scheduled broadcast start, when any. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/live/channels/abcde" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/live/channels/abcde", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/live/channels/abcde", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "channel_id": "abcde", "profile": { "nickname": "리빙하우스", "onair": false, "broadcastExpectedStartDate": "2026-08-10T20:00:00+09:00" } } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # List Live Channel Broadcasts Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-live-channel-broadcasts GET https://scrapebadger.com/v1/naver/shopping/live/channels/{channel_id}/broadcasts Broadcast list for a Naver Shopping Live channel, including upcoming standby schedule cards. List a **Shopping Live channel's broadcasts** — past, live and upcoming — including the STANDBY schedule cards for broadcasts not yet started. Cursor-paginated. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Shopping Live channel id. ## Response Cursor for the next page, or `null` at the end. Broadcast cards. e.g. `ONAIR`, `END`, `STANDBY`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/live/channels/abcde/broadcasts" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/live/channels/abcde/broadcasts", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/live/channels/abcde/broadcasts", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "channel_id": "abcde", "count": 42, "next": "20", "result_count": 20, "broadcasts": [ { "id": "1234567", "title": "여름 침구 특가 라이브", "status": "END", "expectedStartDate": "2026-08-01T20:00:00+09:00" } ] } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # List Live Channel Products Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-live-channel-products GET https://scrapebadger.com/v1/naver/shopping/live/channels/{channel_id}/products Product list for a Naver Shopping Live channel, cursor-paginated. List the **products a Shopping Live channel features** across its broadcasts, cursor-paginated. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Shopping Live channel id. ## Query Parameters Pagination cursor from a prior page. Products per page (1–100). Omit for the upstream default (10). ## Response Cursor for the next page, or `null` at the end. Channel products. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/live/channels/abcde/products?size=20" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/live/channels/abcde/products?" + new URLSearchParams({"size": "20"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/live/channels/abcde/products", headers={"X-API-Key": "YOUR_API_KEY"}, params={"size": "20"}, ) data = res.json() ``` ```json Response theme={null} { "channel_id": "abcde", "count": 120, "next": "20", "result_count": 20, "products": [ { "key": "p1", "name": "시원한 여름 이불", "salePrice": 59000 } ] } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # List Live Channel Shortclips Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-live-channel-shortclips GET https://scrapebadger.com/v1/naver/shopping/live/channels/{channel_id}/shortclips Shorts / clips list for a Naver Shopping Live channel, with sort control and cursor pagination. List a **Shopping Live channel's shortclips** — its short-form shopping clips — with sort control and cursor pagination. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Shopping Live channel id. ## Query Parameters `LATEST`, `VIEW` or `RECOMMEND`. Omit for the upstream default. Pagination cursor from a prior page. Clips per page (1–100). Omit for the upstream default (10). ## Response Cursor for the next page, or `null` at the end. Shortclip cards. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/live/channels/abcde/shortclips?sort_type=VIEW&size=20" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/live/channels/abcde/shortclips?" + new URLSearchParams({"sort_type": "VIEW", "size": "20"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/live/channels/abcde/shortclips", headers={"X-API-Key": "YOUR_API_KEY"}, params={"sort_type": "VIEW", "size": "20"}, ) data = res.json() ``` ```json Response theme={null} { "channel_id": "abcde", "count": 60, "next": "20", "result_count": 20, "shortclips": [ { "id": "sc100", "title": "1분 침구 꿀팁", "thumbnailUrl": "https://shop-phinf.example.net/sc100.jpg", "viewCount": 88213 } ] } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # List Live Replay Products Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-live-replay-products GET https://scrapebadger.com/v1/naver/shopping/live/broadcasts/{broadcast_id}/replay-products The replay product timeline of an ended Naver Shopping Live broadcast — products with their on-air offsets. Fetch the **replay product timeline** of an ended Shopping Live broadcast — the products as they were featured over the broadcast, each entry carrying its on-air offset so you can align products to the replay video. Cursor-paginated. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Shopping Live broadcast id. ## Query Parameters Include products shown before the broadcast started. Pagination cursor; `0` starts from the beginning. ## Response Cursor for the next page, or `null` at the end. Timeline entries in this page. Distinct products across the timeline. Timeline entries. Entry timestamp (epoch ms). Offset into the replay, in seconds. Products featured at this offset. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/live/broadcasts/1234567/replay-products?next=0" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/live/broadcasts/1234567/replay-products?" + new URLSearchParams({"next": "0"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/live/broadcasts/1234567/replay-products", headers={"X-API-Key": "YOUR_API_KEY"}, params={"next": "0"}, ) data = res.json() ``` ```json Response theme={null} { "broadcast_id": "1234567", "next": "20", "result_count": 1, "product_count": 5, "entries": [ { "createdAtMilli": 1754044800000, "offset_seconds": 120, "products": [ { "key": "p1", "name": "시원한 여름 이불", "salePrice": 59000 } ] } ] } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Shopping Live Keyword Rankings Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-live-search-keywords GET https://scrapebadger.com/v1/naver/shopping/live/search/keywords Naver Shopping Live standby search keyword ranking — the keywords trending on the Shopping Live search screen. Fetch the **Shopping Live standby keyword ranking** — the trending keywords shown on the Shopping Live search screen, each with its rank movement, plus the recent-keyword list. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Response The keyword ranking block. Ranked keywords. Rank change. Absolute update timestamp (ISO 8601). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/live/search/keywords" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/live/search/keywords", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/live/search/keywords", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "keyword_ranking": { "keywordRankings": [ { "keyword": "여름 이불", "variation": 2 } ], "updatedAt": "2026-08-07T10:00:00+09:00", "updated_at": "2026-08-07T01:00:00+00:00", "updated_utc": "2026-08-07T01:00:00Z" }, "recent_keywords": [ "캠핑", "원피스" ], "result_count": 20, "source_url": "https://shoppinglive.naver.com/search" } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Get Live Shortclip Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-live-shortclip GET https://scrapebadger.com/v1/naver/shopping/live/shortclips/{shortclip_id} Naver Shopping Live shortclip detail with embedded products and categories. Fetch **Shopping Live shortclip detail** — the clip's channel, video id, product categories and the products embedded in the clip. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Shopping Live shortclip id. ## Response Products embedded in the clip. Shortclip detail. The owning channel. Video id. Product categories in the clip. Embedded products. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/live/shortclips/sc100" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/live/shortclips/sc100", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/live/shortclips/sc100", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "shortclip_id": "sc100", "item_count": 2, "shortclip": { "channel": { "id": "abcde", "nickname": "리빙하우스" }, "vid": "V_ab12cd34", "categories": [ { "id": "c1", "name": "침구" } ], "products": [ { "key": "p1", "name": "시원한 여름 이불", "salePrice": 59000 } ] } } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # List Live Shortclip Products Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-live-shortclip-products GET https://scrapebadger.com/v1/naver/shopping/live/shortclips/{shortclip_id}/products Paginated product list for a Naver Shopping Live shortclip, with attachment-type and sort control. List the **products featured in a Shopping Live shortclip**, paginated, with attachment-type and sort control. **Credits:** 5 `page` is 0-based. ## Authorization Your ScrapeBadger API key. ## Path Parameters Shopping Live shortclip id. ## Query Parameters `MAIN` or `SUB`. 0-based page. Products per page (1–100). `RECOMMEND` or `POPULAR`. ## Response Clip products. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/live/shortclips/sc100/products?sort=POPULAR&size=20" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/live/shortclips/sc100/products?" + new URLSearchParams({"sort": "POPULAR", "size": "20"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/live/shortclips/sc100/products", headers={"X-API-Key": "YOUR_API_KEY"}, params={"sort": "POPULAR", "size": "20"}, ) data = res.json() ``` ```json Response theme={null} { "shortclip_id": "sc100", "page": 0, "total_count": 2, "total_page": 1, "result_count": 2, "products": [ { "key": "p1", "name": "시원한 여름 이불", "salePrice": 59000, "discountedSalePrice": 39000 } ] } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Shopping Price Compare Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-price-compare GET https://scrapebadger.com/v1/naver/shopping/price-compare Seller offers per catalog product from Naver's 가격비교 (price-comparison) page — the lowest-price mall rows for each catalog match. Fetch **seller offers per catalog product** from Naver's 가격비교 (price-comparison) page. For each catalog entry matching the query you get the catalog identity, the total offer count and the first few lowest-price seller rows. **Credits:** 5 Clears Naver's shopping captcha in a live browser session. One page of offers is served per call, and each catalog entry exposes its first 5 lowest-price rows. ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords (1–200 chars). ## Response Catalog entries matching the query. Total seller offers for this catalog entry. Lowest price across sellers, in KRW. The first 5 lowest-price seller rows. That mall's price in KRW. Whether the mall supports Naver Pay. Raw upstream `lowPriceByMallNo` string for the same 5 malls. A note describing the offer-row coverage. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/price-compare?query=다이슨+에어랩" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/price-compare?" + new URLSearchParams({"query": "다이슨 에어랩"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/price-compare", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "다이슨 에어랩"}, ) data = res.json() ``` ```json Response theme={null} { "query": "다이슨 에어랩", "entries": [ { "catalog_id": "82614000777", "catalog_name": "다이슨 에어랩 컴플리트 롱", "offer_count": 214, "best_price": 529000, "offers": [ { "mall_name": "다이슨 공식스토어", "price": 529000, "nv_mid": "82614000777", "product_id": "7008888001", "mall_seq": "41021", "naver_pay": true } ], "price_by_mall": "82614000777/41021/7008888001/529000/1/..." } ], "offers_note": "First 5 low-price rows per catalog entry." } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Shopping Catalog Search Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-search-catalog GET https://scrapebadger.com/v1/naver/shopping/search-catalog Full-catalog Naver Shopping search — deep, paginated product results (pages 1–5) with sort control. Run a **full-catalog Naver Shopping search** against `search.shopping.naver.com`. Unlike the finder preview, this is the deep catalog feed with sort control and pagination through pages 1–5. Each product carries its catalogue identity, price, review stats, delivery fee and category path. **Credits:** 5 This endpoint clears Naver's shopping captcha in a live browser session, so it is the heaviest Naver call and a page can take up to \~90 seconds. Pages are capped at 5; sorted lists are capped upstream at \~120 items. Sponsored rows stay in `products` flagged `is_ad`. ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords (1–200 chars). `RECOMMEND`, `LOW_PRICE`, `HIGH_PRICE`, `PURCHASE`, `REVIEW` or `RECENT`. 1-based page, `1`–`5`. Page 1 is the SSR page; pages 2+ use the catalog XHR. ## Response Total catalog matches, when Naver reports it. Cursor for the next page, when present. Whether another page is available (within the 5-page cap). Always `false` — this is the full catalog feed. Catalog products. Naver Shopping catalogue id. Per-page summary, including the overlap count with earlier pages. Items on this page already seen on an earlier page. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/search-catalog?query=로봇청소기&sort=LOW_PRICE&page=1" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/search-catalog?" + new URLSearchParams({"query": "로봇청소기", "sort": "LOW_PRICE", "page": "1"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/search-catalog", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "로봇청소기", "sort": "LOW_PRICE", "page": "1"}, ) data = res.json() ``` ```json Response theme={null} { "query": "로봇청소기", "sort": "LOW_PRICE", "page": 1, "page_size": 40, "total": 1200, "cursor": 41, "has_more": true, "result_count": 40, "preview_only": false, "products": [ { "rank": 1, "nv_mid": "82613999001", "title": "로보락 S8 로봇청소기", "price": 899000, "discounted_price": 799000, "discount_rate": 11, "image_url": "https://shopping-phinf.example.net/82613999001.jpg", "product_url": "https://shopping.naver.com/catalog/82613999001", "channel_product_id": "7009999001", "mall_name": "로보락 공식스토어", "mall_id": "roborock", "mall_seq": "55123", "review_score": 4.7, "review_count": 8842, "delivery_fee": 0, "category_path": [ "디지털/가전", "생활가전", "청소기" ], "leaf_category_id": "50002100", "is_ad": false } ], "pages": [ { "page": 1, "result_count": 40, "repeated_count": 0 } ], "source_url": "https://search.shopping.naver.com/ns/search?query=로봇청소기" } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Shopping Filtered Search Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-search-filtered GET https://scrapebadger.com/v1/naver/shopping/search-filtered Filtered Naver Shopping product search — narrow a finder query by a brand id and/or attribute id. Run a **filtered Naver Shopping product search** — the same finder feed as [`/shopping/search-products`](/api-reference/endpoint/naver/shopping-search-products), narrowed by a brand id and/or attribute id taken from [`/shopping/search-filters`](/api-reference/endpoint/naver/shopping-search-filters). Returns the finite finder set (up to 10 pages of 8 slots). **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords. A brand value id from `/shopping/search-filters` (`BRAND` facet). An attribute value id from `/shopping/search-filters` (`ATTRIBUTE` facet). ## Response The brand ids applied. The attribute ids applied. Always `true`. Finder pages folded in (≤ 10). Total matches reported by Naver, when available. How the filter was applied: `click` or `rewrite`. Filtered products — same shape as a [`/shopping/search-products`](/api-reference/endpoint/naver/shopping-search-products) product. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/search-filtered?query=무선+이어폰&brand_id=12345" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/search-filtered?" + new URLSearchParams({"query": "무선 이어폰", "brand_id": "12345"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/search-filtered", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "무선 이어폰", "brand_id": "12345"}, ) data = res.json() ``` ```json Response theme={null} { "query": "무선 이어폰", "brand_ids": [ "12345" ], "attribute_ids": [], "preview_only": true, "result_count": 40, "page_count": 5, "page_size": 8, "total_count": 40, "filters_applied_by": "click", "products": [ { "rank": 1, "nv_mid": "82613579214", "product_name": "삼성전자 갤럭시 버즈3 프로", "product_url": "https://shopping.naver.com/catalog/82613579214", "sale_price": 279000, "discounted_sale_price": 229000, "mall_name": "삼성전자 공식스토어", "is_ad": false } ] } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Shopping Search Filters Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-search-filters GET https://scrapebadger.com/v1/naver/shopping/search-filters Query-dependent filter facets (brand, attribute) for a Naver Shopping product search. Return the **filter facets** Naver offers for a product-search query — the brand and attribute filters, each with its selectable values and ids. Feed a value id into [`/shopping/search-filtered`](/api-reference/endpoint/naver/shopping-search-filtered) to narrow a search. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords. ## Response Filter facets returned. Filter facets. `BRAND`, `ATTRIBUTE`, … Selectable values. The dominant category for this query, when Naver resolves one. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/search-filters?query=무선+이어폰" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/search-filters?" + new URLSearchParams({"query": "무선 이어폰"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/search-filters", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "무선 이어폰"}, ) data = res.json() ``` ```json Response theme={null} { "query": "무선 이어폰", "result_count": 2, "filters": [ { "id": "brand", "name": "브랜드", "filter_name": "brand", "type": "BRAND", "source_type": "FINDER", "values": [ { "id": "12345", "name": "삼성전자" }, { "id": "23456", "name": "애플" } ] } ], "category_id": "50000151" } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Shopping Product Search Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-search-products GET https://scrapebadger.com/v1/naver/shopping/search-products Product search across Naver Shopping via the mobile integrated-search finder preview — every preview page in one response. Search products across Naver Shopping using the **mobile integrated-search shopping finder**. One call returns the complete finder preview (all preview pages at once), each product carrying its catalogue id, mall, price, discount, review score and category path. **Credits:** 5 This is the **finder preview** — one response holds every preview page. Deep full-catalog pagination is served by [`/shopping/search-catalog`](/api-reference/endpoint/naver/shopping-search-catalog). ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords. Finder tab: `m_view` or `m_shop`. ## Response Always `true` — see the note above. Preview pages folded into this response. Finder product cards. Naver Shopping catalogue id. List price in KRW. Wishlist (“찜”) count. `AD` or `SAS`. Large category id. Medium category id. Small category id. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/search-products?query=무선+이어폰&tab=m_view" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/search-products?" + new URLSearchParams({"query": "무선 이어폰", "tab": "m_view"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/search-products", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "무선 이어폰", "tab": "m_view"}, ) data = res.json() ``` ```json Response theme={null} { "query": "무선 이어폰", "tab": "m_view", "preview_only": true, "result_count": 80, "total_pages": 10, "products": [ { "rank": 1, "nv_mid": "82613579214", "product_id": "5123456789", "channel_product_id": "7001234567", "mall_id": "samsung", "mall_name": "삼성전자 공식스토어", "mall_url": "https://brand.naver.com/samsung", "product_name": "삼성전자 갤럭시 버즈3 프로", "product_url": "https://shopping.naver.com/catalog/82613579214", "sale_price": 279000, "discounted_sale_price": 229000, "discounted_ratio": 18, "price_currency": "KRW", "images": [ "https://shopping-phinf.example.net/82613579214.jpg" ], "average_review_score": 4.8, "total_review_count": 12043, "purchase_count": 5321, "keep_count": 8820, "is_ad": false, "source_type": "SAS", "l_cat_id": "50000003", "m_cat_id": "50000151", "s_cat_id": "50000806", "leaf_category_id": "50002345" } ] } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Shopping Vertical Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/shopping-vertical GET https://scrapebadger.com/v1/naver/shopping/verticals/{vertical} Curated Naver Shopping products for a named snxbest vertical such as fashiontown, shoppinglive or logistics. Fetch the **curated product list for a named Naver Shopping vertical** — the editorial feeds behind the `fashiontown`, `shoppinglive` and `logistics` sections. Returns a fixed set of 12 curated products. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters One of `fashiontown`, `shoppinglive` or `logistics`. ## Response Echo of the requested vertical. Products returned (12). Curated products — same shape as a [`/shopping/deals`](/api-reference/endpoint/naver/shopping-deals) product. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/shopping/verticals/fashiontown" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/shopping/verticals/fashiontown", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/shopping/verticals/fashiontown", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "vertical": "fashiontown", "result_count": 12, "products": [ { "rank": 1, "nv_mid": "82613579300", "title": "남성 오버핏 셔츠", "image_url": "https://shopping-phinf.example.net/82613579300.jpg", "link_url": "https://shopping.naver.com/catalog/82613579300", "price": 49000, "discount_price": 34300, "discount_rate": 30, "labels": [ "무료배송" ], "is_ad": false } ] } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Get Store Bestsellers Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/store-bestsellers GET https://scrapebadger.com/v1/naver/stores/{store_url}/bestsellers Bestselling products within a single Naver SmartStore / Brand Store, by period. List the **bestselling products within one storefront**, scoped by period. Each product is the same storefront listing card returned by [`/stores/{store_url}/products`](/api-reference/endpoint/naver/store-products). **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Storefront slug. ## Query Parameters Storefront host: `smartstore` or `brand`. `REALTIME`, `DAILY`, `WEEKLY` or `MONTHLY`. ## Response Bestselling storefront listing cards — same shape as [`/stores/{store_url}/products`](/api-reference/endpoint/naver/store-products). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/stores/plusink/bestsellers?host=smartstore&period=DAILY" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/stores/plusink/bestsellers?" + new URLSearchParams({"host": "smartstore", "period": "DAILY"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/stores/plusink/bestsellers", headers={"X-API-Key": "YOUR_API_KEY"}, params={"host": "smartstore", "period": "DAILY"}, ) data = res.json() ``` ```json Response theme={null} { "store_url": "plusink", "host": "smartstore", "period": "DAILY", "result_count": 20, "products": [ { "id": "7001234567", "name": "정품 HP 잉크 카트리지 세트", "sale_price": 48000, "representative_image_url": "https://shop-phinf.example.net/7001234567.jpg" } ] } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Get Store Categories Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/store-categories GET https://scrapebadger.com/v1/naver/stores/{store_url}/categories The display-category tree of a Naver SmartStore / Brand Store storefront. Fetch the **display-category tree** of a storefront — the seller-defined categories shoppers browse the store by, returned recursively with level and sort order. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Storefront slug. ## Query Parameters Storefront host: `smartstore` or `brand`. ## Response Display categories. Whether this is the catch-all “전체상품” node. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/stores/plusink/categories?host=smartstore" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/stores/plusink/categories?" + new URLSearchParams({"host": "smartstore"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/stores/plusink/categories", headers={"X-API-Key": "YOUR_API_KEY"}, params={"host": "smartstore"}, ) data = res.json() ``` ```json Response theme={null} { "store_url": "plusink", "host": "smartstore", "result_count": 4, "categories": [ { "category_id": "1000000001", "parent_category_id": null, "name": "전체상품", "level": 1, "sort_order": 0, "all_product_category": true, "exposure": true, "type": "MANUAL" } ] } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Get Store Products Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/store-products GET https://scrapebadger.com/v1/naver/stores/{store_url}/products Paginated product listing for a Naver SmartStore / Brand Store, optionally scoped to a display category. List the **products in a storefront**, optionally scoped to one of its display categories. Each product is the storefront listing card — name, price, discount, stock status, review summary and representative image. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Path Parameters Storefront slug. ## Query Parameters Storefront host: `smartstore` or `brand`. Scope to a display category id from [`/stores/{store_url}/categories`](/api-reference/endpoint/naver/store-categories). 1-based page. Products per page. Sort order, e.g. `POPULARITY`. Storefront channel uid. Optional — resolved from the slug when omitted. ## Response Total products in scope. Storefront listing cards. Channel product number. e.g. `SALE`, `SOLDOUT`. Discount view. Whether same-day (“오늘출발”) delivery is offered. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/stores/plusink/products?host=smartstore&page=1&size=20" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/stores/plusink/products?" + new URLSearchParams({"host": "smartstore", "page": "1", "size": "20"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/stores/plusink/products", headers={"X-API-Key": "YOUR_API_KEY"}, params={"host": "smartstore", "page": "1", "size": "20"}, ) data = res.json() ``` ```json Response theme={null} { "store_url": "plusink", "host": "smartstore", "total_count": 312, "page": 1, "page_size": 20, "sort": "POPULARITY", "products": [ { "id": "7001234567", "product_no": "5123456789", "name": "정품 HP 잉크 카트리지 세트", "disp_name": "정품 HP 잉크 세트", "sale_price": 48000, "disp_sale_price": 48000, "product_status_type": "SALE", "stock_quantity": 820, "category": { "category_id": "50006543", "category_name": "잉크/토너", "whole_category_id": "50000003>50006543", "whole_category_name": "디지털/가전>잉크/토너" }, "channel": { "channel_no": "10012345", "account_no": "90012345", "channel_uid": "2sV!abc123", "channel_name": "플러스잉크" }, "benefits_view": { "discounted_sale_price": 42000, "discounted_ratio": 13 }, "review_amount": { "total_review_count": 2841, "average_review_score": 4.9, "product_satisfaction_percent": 98 }, "representative_image_url": "https://shop-phinf.example.net/7001234567.jpg", "is_free_delivery": true, "today_delivery": true } ] } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Get Store Profile Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/store-profile GET https://scrapebadger.com/v1/naver/stores/{store_url} Naver SmartStore / Brand Store seller profile — channel name, description, logo, follower and sale counts, seller grade. Fetch a **Naver SmartStore or Brand Store seller profile** by its storefront slug. Returns the channel name and description, logo, SNS links, follower and sale counts, seller grade, CS response ratio and business type. **Credits:** 5 Personal identity fields (names, phone numbers, addresses, emails) are masked and omitted from the response. ## Authorization Your ScrapeBadger API key. ## Path Parameters Storefront slug, e.g. `plusink` or `drbrian`. ## Query Parameters Storefront host: `smartstore` or `brand`. ## Response Social links the store publishes. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/stores/plusink?host=smartstore" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/stores/plusink?" + new URLSearchParams({"host": "smartstore"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/stores/plusink", headers={"X-API-Key": "YOUR_API_KEY"}, params={"host": "smartstore"}, ) data = res.json() ``` ```json Response theme={null} { "store_url": "plusink", "host": "smartstore", "channel_uid": "2sV!abc123", "channel_no": "10012345", "channel_name": "플러스잉크", "description": "정품 프린터 잉크 전문 스토어", "logo_url": "https://shop-phinf.example.net/logo/plusink.jpg", "sns": {}, "follower_count": 48213, "seller_grade": "빅파워", "sale_count": 152043, "cs_response_ratio": "98%", "business_type": "법인", "represent_type": "SmartStore", "channel_service_type": "STOREFARM" } ``` ## Errors | Status | Meaning | | - | - | | `404` | The requested resource does not exist or has been removed. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Video Search Source: https://docs.scrapebadger.com/api-reference/endpoint/naver/video GET https://scrapebadger.com/v1/naver/video Search the Naver video vertical — 48 videos per page with duration, channel, view count and thumbnail. Search the **Naver video** vertical, which aggregates videos across YouTube, Naver TV and other sources. Each result carries the title and URL, duration, channel name and URL, view count, source and an absolute publish timestamp. Returns 48 videos per page. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords. 1-based result page. Each page returns up to 48 videos. ## Response Videos. Video URL. Runtime as displayed, e.g. `12:04`. Platform, e.g. `YouTube`, `네이버TV`. Absolute publish timestamp (ISO 8601). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/video?query=제주도+브이로그&page=1" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/video?" + new URLSearchParams({"query": "제주도 브이로그", "page": "1"}), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/video", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "제주도 브이로그", "page": "1"}, ) data = res.json() ``` ```json Response theme={null} { "query": "제주도 브이로그", "page": 1, "result_count": 48, "results": [ { "position": 1, "title": "제주도 3박4일 브이로그", "url": "https://tv.naver.com/v/12345", "duration": "12:04", "channel": "여행하는쩡", "channel_url": "https://tv.naver.com/jjeong", "source": "네이버TV", "view_count": 48213, "thumbnail_url": "https://video-phinf.example.net/12345.jpg", "published": "2026.06.01.", "published_at": "2026-06-01T00:00:00+09:00" } ] } ``` ## Errors | Status | Meaning | | - | - | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | # Location Suggestions Source: https://docs.scrapebadger.com/api-reference/endpoint/realtor/autocomplete GET /v1/realtor/autocomplete Autocomplete locations (cities, ZIPs, neighborhoods, addresses) for a partial query. ## Query Parameters Partial location to autocomplete (e.g. `austi`, `9021`, `toron`). Which market to source suggestions from: `us` (realtor.com) or `ca` (realtor.ca). Maximum number of suggestions to return. Range: `1` - `25`. ## Response The market the suggestions came from. The query prefix that was autocompleted. Array of suggestion objects. Suggestion id. Suggestion type, e.g. `city`, `postal_code`, `neighborhood`, `address`. Human-readable label, e.g. `Austin, TX`. City (nullable). State/province code (nullable). Postal/ZIP code (nullable). ISO country code (nullable). Portal slug id (nullable). Portal geo id (nullable). Center coordinate `{lat, lon}` (nullable). Market the suggestion belongs to. ### Example Response ```json theme={null} { "market": "us", "query": "austi", "suggestions": [ { "id": "city:austin_tx", "type": "city", "label": "Austin, TX", "city": "Austin", "state_code": "TX", "postal_code": null, "country": "US", "slug_id": "Austin_TX", "geo_id": "1234", "coordinate": { "lat": 30.2672, "lon": -97.7431 }, "market": "us" } ] } ``` Each autocomplete request costs **2 credits**. Failed requests are not charged. # Get Property Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/realtor/get-property GET /v1/realtor/properties/{property_id} Full detail for a single property — price/tax history, schools, amenities, agents, and estimates. ## Path Parameters The portal property id. You can find this in search results or extract it from a listing URL. ## Query Parameters Which market the property lives in: `us` (realtor.com) or `ca` (realtor.ca). ## Response The response is a `PropertyDetail` object returned at the top level (no wrapper). It contains every field of a search-result `Property` plus the detail-only fields below. Portal property id. Portal listing id (nullable). MLS number (nullable). Market (`us` or `ca`). ISO country code. Full URL to the listing. Listing status (`for_sale`, `for_rent`, `sold`, `pending`). ISO 4217 currency code. List price (nullable). Human-formatted price (nullable). Price per square foot (nullable). Monthly HOA fee (nullable). Property type (nullable). Bedrooms (nullable). Bathrooms (nullable). Interior square footage (nullable). Lot square footage (nullable). Year built (nullable). Address with `line`, `city`, `state`, `state_code`, `postal_code`, `country`, `neighborhood`, `county`, and `coordinate` (`{lat, lon}`). Listing description (nullable). Primary photo URL (nullable). Total number of photos. Photo objects with `href`, `href_high`, `href_med`, `href_low`, `tags[]`, `description`. Virtual tour URLs. Video URLs. Boolean flags: `is_new_listing`, `is_pending`, `is_contingent`, `is_foreclosure`, `is_new_construction`, `is_price_reduced`, `is_coming_soon`. Days on market (nullable). Listing agents. Agent id. Full name. First name (nullable). Last name (nullable). Title (nullable). Agent type, e.g. `seller`, `buyer` (nullable). Email (nullable). Phone objects with `number`, `type`, `ext`, `primary`. Agent photo URL (nullable). Agent profile URL (nullable). Office with `name`, `email`, `href`, `logo`, `phones[]`, `address`. Brokerage name (nullable). NRDS id (nullable). State license number (nullable). Open house objects with `start_utc`, `start_at`, `end_utc`, `end_at`, `description`, `time_zone`, `href`. Grouped listing details. Detail category, e.g. `Interior Features`. List of detail strings in the category. List of amenity strings. Yearly tax records. Tax year. Tax amount (nullable). Building assessment (nullable). Land assessment (nullable). Total assessment (nullable). Price / listing events over time. Event date as a Unix timestamp (nullable). Event date as an ISO-8601 string (nullable). Event type, e.g. `Listed`, `Sold`, `Price Changed`. Price at the event (nullable). Price per sqft at the event (nullable). Source listing id (nullable). Nearby schools. School name. School rating (nullable). Education levels served, e.g. `["elementary"]`. Grade range, e.g. `K-5` (nullable). Distance from the property in miles (nullable). School district (nullable). Value estimates. Estimate source. Point estimate (nullable). High estimate (nullable). Low estimate (nullable). Estimate date as a Unix timestamp (nullable). Estimate date as an ISO-8601 string (nullable). ### Example Response ```json theme={null} { "property_id": "1234567890", "listing_id": "2960000001", "mls_number": "ACT1234567", "market": "us", "country": "US", "url": "https://www.realtor.com/realestateandhomes-detail/1234567890", "status": "for_sale", "currency": "USD", "list_price": 450000, "list_price_formatted": "$450,000", "price_per_sqft": 250, "hoa_fee": 45, "property_type": "single_family", "beds": 3, "baths": 2, "sqft": 1800, "lot_sqft": 6500, "year_built": 2015, "address": { "line": "123 Main St", "city": "Austin", "state": "Texas", "state_code": "TX", "postal_code": "78701", "country": "US", "neighborhood": "Downtown", "county": "Travis", "coordinate": { "lat": 30.2672, "lon": -97.7431 } }, "primary_photo": "https://ap.rdcpix.com/abc/s.jpg", "photo_count": 32, "days_on_market": 4, "agents": [ { "agent_id": "A1", "name": "Jane Doe", "email": "jane@realty.com", "phones": [{ "number": "512-555-0100", "type": "mobile", "primary": true }], "office": { "name": "Downtown Realty", "href": "https://www.realtor.com/realestateagency/..." }, "broker": "Downtown Realty Group" } ], "details": [ { "category": "Interior Features", "text": ["Hardwood floors", "Granite countertops"] } ], "amenities": ["Pool", "Garage"], "tax_history": [ { "year": 2024, "tax": 6200, "assessment_building": 300000, "assessment_land": 120000, "assessment_total": 420000 } ], "price_history": [ { "date_at": "2026-06-01T00:00:00Z", "event": "Listed", "price": 450000, "price_per_sqft": 250 } ], "schools": [ { "name": "Austin Elementary", "rating": 8, "education_levels": ["elementary"], "grades": "K-5", "distance_miles": 0.4, "district": "Austin ISD" } ], "estimates": [ { "source": "realtor", "estimate": 455000, "estimate_high": 475000, "estimate_low": 435000, "date_at": "2026-06-20T00:00:00Z" } ] } ``` Each property-detail request costs **10 credits**. Failed requests are not charged. # List Markets Source: https://docs.scrapebadger.com/api-reference/endpoint/realtor/list-markets GET /v1/realtor/markets List all supported realtor markets with their portals, currencies, and locales. ## Response Array of supported markets. Market code to use in the `market` query parameter (`us` or `ca`). Portal domain (`realtor.com` or `realtor.ca`). ISO 3166-1 alpha-2 country code. ISO 4217 currency code used in this market. BCP-47 locale (e.g. `en-US`). Market country name. ### Example Response ```json theme={null} { "markets": [ { "code": "us", "domain": "realtor.com", "country": "US", "currency": "USD", "locale": "en-US", "name": "United States" }, { "code": "ca", "domain": "realtor.ca", "country": "CA", "currency": "CAD", "locale": "en-CA", "name": "Canada" } ] } ``` Listing markets is a **free** reference endpoint (0 credits). # Search Listings Source: https://docs.scrapebadger.com/api-reference/endpoint/realtor/search GET /v1/realtor/search Search a realtor.com (US) or realtor.ca (CA) market for property listings. ## Query Parameters Free-text location: a city ("Austin, TX"), a ZIP/postal code, or a region ("Toronto, ON"). Required unless you pass a Canada bounding box (`lat_min`/`lat_max`/`lng_min`/`lng_max`). Which market to search: `us` (realtor.com, USD) or `ca` (realtor.ca, CAD). Listing status filter. | Value | Description | | - | - | | `for_sale` | Active for-sale listings (default) | | `for_rent` | Rental listings | | `sold` | Recently sold listings | | `pending` | Pending / under contract | Minimum list price in the market's local currency. Maximum list price in the market's local currency. Minimum number of bedrooms. Minimum number of bathrooms. Minimum interior square footage. **US market only.** Maximum interior square footage. **US market only.** Comma-separated list of property types. **US market only.** Values: `single_family`, `condos`, `townhomes`, `multi_family`, `mobile`, `land`. Sort order for results. | Value | Description | | - | - | | `relevant` | Best match (default) | | `newest` | Most recently listed | | `price_low` | Cheapest first | | `price_high` | Most expensive first | | `photo_count` | Most photos first | Page number for paginated results. Results per page. Range: `1` - `200`. South edge of a bounding box. **Canada power-user option** (realtor.ca caps \~600 results per box). North edge of a bounding box. **Canada only.** West edge of a bounding box. **Canada only.** East edge of a bounding box. **Canada only.** ## Response The market that was searched (`us` or `ca`). ISO 3166-1 alpha-2 country code for the market (`US` or `CA`). Total number of matching listings. Number of listings returned on this page. Current page number. Total number of pages available. Array of matching properties. Portal property id. Portal listing id (nullable). MLS number (nullable). Market (`us` or `ca`). ISO country code. Full URL to the listing. Listing status (`for_sale`, `for_rent`, `sold`, `pending`). `sale` or `rent` (nullable). ISO 4217 currency code. List price (nullable). Human-formatted price, e.g. `$450,000` (nullable). Lower bound of a price range, if listed as a range (nullable). Upper bound of a price range (nullable). Price per square foot (nullable). Amount the price was reduced (nullable). Last sold price (nullable). Last sold date as a Unix timestamp (nullable). Last sold date as an ISO-8601 string (nullable). Monthly HOA fee (nullable). Property type (e.g. `single_family`) (nullable). Property sub-type (nullable). Number of bedrooms (nullable). Total number of bathrooms (nullable). Full bathrooms (nullable). Half bathrooms (nullable). Interior square footage (nullable). Lot square footage (nullable). Year the property was built (nullable). Number of stories (nullable). Garage spaces (nullable). Total rooms (nullable). Parking spaces (nullable). Address with `line`, `city`, `state`, `state_code`, `postal_code`, `country`, `neighborhood`, `county`, and `coordinate` (`{lat, lon}`). Listing description (nullable). Primary photo URL (nullable). Total number of photos. Photo objects with `href`, `href_high`, `href_med`, `href_low`, `tags[]`, `description`. Virtual tour URLs. Video URLs. Boolean flags: `is_new_listing`, `is_pending`, `is_contingent`, `is_foreclosure`, `is_new_construction`, `is_price_reduced`, `is_coming_soon`. Feature tags. List date as a Unix timestamp (nullable). List date as an ISO-8601 string (nullable). Last update as a Unix timestamp (nullable). Last update as an ISO-8601 string (nullable). Days on market (nullable). Listing agents (see the [Agent object](/api-reference/endpoint/realtor/get-property)). Source MLS id (nullable). Source MLS name (nullable). Open house objects with `start_utc`, `start_at`, `end_utc`, `end_at`, `description`, `time_zone`, `href`. ### Example Response ```json theme={null} { "market": "us", "country": "US", "total": 842, "count": 20, "page": 1, "total_pages": 43, "results": [ { "property_id": "1234567890", "listing_id": "2960000001", "mls_number": "ACT1234567", "market": "us", "country": "US", "url": "https://www.realtor.com/realestateandhomes-detail/1234567890", "status": "for_sale", "transaction_type": "sale", "currency": "USD", "list_price": 450000, "list_price_formatted": "$450,000", "price_per_sqft": 250, "hoa_fee": 45, "property_type": "single_family", "beds": 3, "baths": 2, "baths_full": 2, "baths_half": 0, "sqft": 1800, "lot_sqft": 6500, "year_built": 2015, "address": { "line": "123 Main St", "city": "Austin", "state": "Texas", "state_code": "TX", "postal_code": "78701", "country": "US", "neighborhood": "Downtown", "county": "Travis", "coordinate": { "lat": 30.2672, "lon": -97.7431 } }, "primary_photo": "https://ap.rdcpix.com/abc/s.jpg", "photo_count": 32, "flags": { "is_new_listing": true, "is_price_reduced": false }, "days_on_market": 4, "agents": [{ "agent_id": "A1", "name": "Jane Doe", "email": "jane@realty.com" }] } ] } ``` Each search request costs **8 credits**. Failed requests are not charged. # Get Posts by Domain Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/get-domain-posts GET /v1/reddit/domains/{domain}/posts Get Reddit posts that link to a specific external domain (e.g. github.com). # Get New Subreddits Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/get-new-subreddits GET /v1/reddit/subreddits/new Get recently created subreddits. # Get Popular Subreddits Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/get-popular-subreddits GET /v1/reddit/subreddits/popular Get the most popular subreddits by subscriber count. # Get Post Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/get-post GET /v1/reddit/posts/{post_id} Get full details for a single Reddit post by ID. # Get Post Comments Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/get-post-comments GET /v1/reddit/posts/{post_id}/comments Get the full nested comment tree for a Reddit post. Supports configurable depth (0-10 levels). # Get Post Duplicates Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/get-post-duplicates GET /v1/reddit/posts/{post_id}/duplicates Get cross-posts and duplicate links for a Reddit post. # Get Subreddit Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/get-subreddit GET /v1/reddit/subreddits/{subreddit} Get full metadata for a subreddit — subscribers, description, rules, banner, theme. # Get Subreddit Posts Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/get-subreddit-posts GET /v1/reddit/subreddits/{subreddit}/posts Get posts from a specific subreddit with sort options (hot/new/top/rising/controversial). # Get Subreddit Rules Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/get-subreddit-rules GET /v1/reddit/subreddits/{subreddit}/rules Get the rules of a subreddit. # List Wiki Pages Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/get-subreddit-wiki GET /v1/reddit/subreddits/{subreddit}/wiki List all wiki page names in a subreddit. # Get Wiki Page Content Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/get-subreddit-wiki-page GET /v1/reddit/subreddits/{subreddit}/wiki/{page} Get the markdown and HTML content of a specific wiki page. # Get Trending Posts Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/get-trending-posts GET /v1/reddit/posts/trending Get trending posts from Reddit's front page across all subreddits. # Get User Profile Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/get-user GET /v1/reddit/users/{username} Get a Reddit user's profile — karma breakdown, account age, verification status. # Get User Comments Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/get-user-comments GET /v1/reddit/users/{username}/comments Get comments authored by a Reddit user. # Get Moderated Subreddits Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/get-user-moderated GET /v1/reddit/users/{username}/moderated Get the list of subreddits a user moderates. # Get User Posts Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/get-user-posts GET /v1/reddit/users/{username}/posts Get posts submitted by a Reddit user. # Get User Trophies Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/get-user-trophies GET /v1/reddit/users/{username}/trophies Get a user's trophy case (badges and awards earned). # Search Posts Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/search-posts GET /v1/reddit/search/posts Search Reddit posts globally or within a subreddit. Supports Reddit's full query syntax (title:, author:, subreddit:, flair:, AND/OR/NOT). # Search Subreddits Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/search-subreddits GET /v1/reddit/search/subreddits Search for subreddits by keyword. # Search Users Source: https://docs.scrapebadger.com/api-reference/endpoint/reddit/search-users GET /v1/reddit/search/users Search for Reddit users by keyword. # Get Broadcast Details Source: https://docs.scrapebadger.com/api-reference/endpoint/spaces/get-broadcast-details get /v1/twitter/spaces/broadcast/{broadcast_id} Get details of a live video broadcast on Twitter. Returns broadcast metadata including title, current state, media key, dimensions, viewer counts, and timestamps. Useful for monitoring live content on the platform. # Get Space Details Source: https://docs.scrapebadger.com/api-reference/endpoint/spaces/get-space-details get /v1/twitter/spaces/{space_id} Get details of a Twitter Space (audio room). Returns Space metadata including title, current state, creator information, participant counts, and scheduling details. Useful for monitoring live audio content and upcoming events. # Create Stream Monitor Source: https://docs.scrapebadger.com/api-reference/endpoint/streams/create-stream-monitor post /v1/twitter/stream/monitors Create a new stream monitor to track one or more Twitter accounts in real time. New tweets from monitored accounts are delivered via WebSocket and optionally via webhook. Each monitored account consumes credits per day based on volume pricing. # Create Webhook Source: https://docs.scrapebadger.com/api-reference/endpoint/streams/create-webhook post /v1/twitter/stream/webhooks Create a new webhook endpoint for a stream monitor. Webhooks receive HMAC-SHA256 signed POST requests when new tweets are detected. # Delete Stream Monitor Source: https://docs.scrapebadger.com/api-reference/endpoint/streams/delete-stream-monitor delete /v1/twitter/stream/monitors/{monitor_id} Permanently delete a stream monitor and stop all associated monitoring. This action cannot be undone. # Delete Webhook Source: https://docs.scrapebadger.com/api-reference/endpoint/streams/delete-webhook delete /v1/twitter/stream/webhooks/{webhook_id} Permanently delete a webhook endpoint. The stream monitor will continue operating but will no longer deliver to this webhook URL. # Get Stream Monitor Source: https://docs.scrapebadger.com/api-reference/endpoint/streams/get-stream-monitor get /v1/twitter/stream/monitors/{monitor_id} Retrieve details of a specific stream monitor by its ID. Returns full monitor configuration, status, and pricing information. # List Billing Logs Source: https://docs.scrapebadger.com/api-reference/endpoint/streams/list-billing-logs get /v1/twitter/stream/billing-logs List billing logs for stream monitors. Shows credit deductions with billing cadence details, tier rates, and account counts. Useful for tracking streaming costs and verifying billing accuracy. # List Delivery Logs Source: https://docs.scrapebadger.com/api-reference/endpoint/streams/list-delivery-logs get /v1/twitter/stream/logs List tweet delivery logs for stream monitors. Shows each detected tweet with detection latency, delivery status, and webhook response details. Useful for monitoring stream health and debugging delivery issues. # List Stream Monitors Source: https://docs.scrapebadger.com/api-reference/endpoint/streams/list-stream-monitors get /v1/twitter/stream/monitors List all stream monitors for the authenticated API key. Supports pagination and optional filtering by status. # List Webhooks Source: https://docs.scrapebadger.com/api-reference/endpoint/streams/list-webhooks get /v1/twitter/stream/webhooks List all webhooks for the authenticated API key. Optionally filter by monitor ID. # Test Webhook Source: https://docs.scrapebadger.com/api-reference/endpoint/streams/test-webhook post /v1/twitter/stream/webhooks/test Send a test payload to the webhook configured for a stream monitor. Returns the HTTP status code and response time from the webhook endpoint. Useful for verifying webhook connectivity before going live. # Update Stream Monitor Source: https://docs.scrapebadger.com/api-reference/endpoint/streams/update-stream-monitor patch /v1/twitter/stream/monitors/{monitor_id} Update an existing stream monitor. All fields are optional; only provided fields will be updated. Use status field to pause or resume monitoring. # Get Ad Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/get-ad-detail GET /v1/tiktok/ads/{ad_id} A single TikTok ad's advertiser, creatives, and the full EU-DSA targeting and impression breakdown — per-region impressions by age and gender, audience size, interests, countries, languages and devices. The TikTok Ad Library is **EU-only** (EU Digital Services Act ad transparency). Pass an ad `id` from a [Search the Ad Library](/api-reference/endpoint/tiktok/search-ads) result and an EU `region`. Each request costs **8 credits**. Failed requests are not charged. The real per-region impression numbers live in `targeting.location.data[].breakdowns` (by age and gender). The top-level `impression` and `spent` fields are usually `0`/`""` for EU disclosures — sum the breakdowns to size a campaign's reach. # Get Comment Replies Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/get-comment-replies GET /v1/tiktok/comments/{comment_id}/replies Replies to a specific comment on a video. Each request costs **8 credits**. Failed requests are not charged. # Get Comments Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/get-comments GET /v1/tiktok/videos/{video_id}/comments Top-level comments on a TikTok video, with cursor pagination. Each request costs **8 credits**. Failed requests are not charged. # Get Hashtag Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/get-hashtag GET /v1/tiktok/hashtags/{name} TikTok hashtag/challenge detail (video count, view count, cover). Each request costs **5 credits**. Failed requests are not charged. # Get Hashtag Videos Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/get-hashtag-videos GET /v1/tiktok/hashtags/{name}/videos Videos tagged with a given TikTok hashtag, with cursor pagination. Each request costs **8 credits**. Failed requests are not charged. # Get Music Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/get-music GET /v1/tiktok/music/{music_id} Detail for a TikTok sound/music entity (title, author, usage counts). Each request costs **5 credits**. Failed requests are not charged. # Get Music Videos Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/get-music-videos GET /v1/tiktok/music/{music_id}/videos Videos that use a given TikTok sound, with cursor pagination. Each request costs **8 credits**. Failed requests are not charged. # Get oEmbed Metadata Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/get-oembed GET /v1/tiktok/oembed Cheap, unauthenticated oEmbed metadata for a TikTok video or profile URL. Each request costs **2 credits**. Failed requests are not charged. # Get Related Videos Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/get-related-videos GET /v1/tiktok/videos/{video_id}/related TikTok's recommended/related videos for a given video. Each request costs **8 credits**. Failed requests are not charged. # Get Transcript Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/get-transcript GET /v1/tiktok/videos/{video_id}/transcript Subtitle/caption tracks and the ASR voice-to-text transcript for a video. Each request costs **10 credits**. Failed requests are not charged. # Get user followers Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/get-user-followers GET /v1/tiktok/users/{username}/followers Retrieve the public followers list that TikTok exposes to a guest. Each successful request costs **10 credits**. No TikTok account is required. Pass `pagination.cursor` unchanged with the same username and region to continue. Cursors last up to 15 minutes and may expire earlier if the guest session is replaced. An expired cursor returns 410; restart from the first page. Private or hidden data returns 403. Temporary upstream failures return 503. Guest lists can be partial even when the profile reports a larger total. # Get user following Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/get-user-following GET /v1/tiktok/users/{username}/following Retrieve the public following list that TikTok exposes to a guest. Each successful request costs **10 credits**. No TikTok account is required. Pass `pagination.cursor` unchanged with the same username and region to continue. Cursors last up to 15 minutes and may expire earlier if the guest session is replaced. An expired cursor returns 410; restart from the first page. Private or hidden data returns 403. Temporary upstream failures return 503. Guest lists can be partial even when the profile reports a larger total. # Get user liked Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/get-user-liked GET /v1/tiktok/users/{username}/liked Retrieve the public liked list that TikTok exposes to a guest. Each successful request costs **10 credits**. No TikTok account is required. Pass `pagination.cursor` unchanged with the same username and region to continue. Cursors last up to 15 minutes and may expire earlier if the guest session is replaced. An expired cursor returns 410; restart from the first page. Private or hidden data returns 403. Temporary upstream failures return 503. Guest lists can be partial even when the profile reports a larger total. # Get User Profile Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/get-user-profile GET /v1/tiktok/users/{username} Full TikTok user profile by @handle (stats, verification, links, avatars). Each profile request costs **5 credits**. Failed requests are not charged. # Get User Reposts Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/get-user-reposts GET /v1/tiktok/users/{username}/reposts Videos a TikTok user has reposted to their profile. Each request costs **8 credits**. Failed requests are not charged. # Get User Videos Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/get-user-videos GET /v1/tiktok/users/{username}/videos A user's posted videos, newest first, with cursor pagination. Each request costs **8 credits**. Failed requests are not charged. Pass `pagination.cursor` unchanged with the same username and region to continue. Guest cursors last up to 15 minutes and can expire earlier when their session is replaced (HTTP 410). Public metadata can omit native-only fields. CDN links may return 403 and are not guaranteed downloads. # Get Video Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/get-video-detail GET /v1/tiktok/videos/{video_id} Full metadata for a single TikTok video or photo slideshow. Pass the author's `username` to skip the internal oEmbed author lookup for a faster, cheaper fetch. Each request costs **5 credits**. Failed requests are not charged. ## Downloading video media Fetch video detail immediately before downloading. When available, `video.video.media_headers` contains the anonymous CDN headers that must accompany **that same response's** `play_addr` or `download_addr`. Do not mix a URL from a list response with headers from video detail. No TikTok account or login cookie is needed. ```python theme={null} media = response["video"]["video"] headers = media.get("media_headers") if headers: download = requests.get(media["play_addr"], headers=headers, stream=True, timeout=30) download.raise_for_status() ``` The headers contain a short-lived guest media cookie, not your ScrapeBadger API key. Send them only to the returned TikTok media URL. Do not send your ScrapeBadger key to the CDN. Refresh video detail if the link expires. If `media_headers` is null, metadata is available but authorized media resolution was not obtained; do not treat this as a verified downloadable link. Photo slideshows may have no video media. Social-list requests accept count up to 50, but TikTok permits at most 30 per upstream page. A response may contain fewer rows; follow its returned cursor. # List Regions Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/list-regions GET /v1/tiktok/regions List supported TikTok content regions. The regions list is **free** (0 credits). # General Search Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/search GET /v1/tiktok/search General TikTok search — video results from the Top feed. Each request costs **5 credits**. Failed requests are not charged. # Search the Ad Library Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/search-ads GET /v1/tiktok/ads/search Search TikTok's EU Commercial Content (ad transparency) Library by keyword or advertiser id. The TikTok Ad Library is **EU-only** (EU Digital Services Act ad transparency). Use an EU `region` such as `DE`, `FR`, `IE`, or `NL`. Pass `advertiser_id` to scope to a single advertiser, or `query` for a keyword search. Each request costs **5 credits**. Failed requests are not charged. # Search Advertisers Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/search-advertisers GET /v1/tiktok/ads/advertisers Look up TikTok advertiser business ids by name, then feed the id into the Ad Library search to list every ad an advertiser runs. The TikTok Ad Library is **EU-only** (EU Digital Services Act ad transparency). Use an EU `region` such as `DE`, `FR`, `IE`, or `NL`. Matching is on the **legal entity name, not the brand**. Searching `nike` returns entities like `NIKE Retail B.V.` and `NIKE COM SRL` — a brand often spans several legal entities, and some are only discoverable via an ad's `advertiser.adv_biz_ids` on [Get Ad Detail](/api-reference/endpoint/tiktok/get-ad-detail). Each request costs **5 credits**. Failed requests are not charged. Full workflow: **Search Advertisers** (`?query=Nike`) → take an advertiser `id` → [Search the Ad Library](/api-reference/endpoint/tiktok/search-ads) (`?advertiser_id=`) → take an ad `id` → [Get Ad Detail](/api-reference/endpoint/tiktok/get-ad-detail). # Search Hashtags Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/search-hashtags GET /v1/tiktok/search/hashtags Search TikTok hashtags by keyword. Each request costs **5 credits**. Failed requests are not charged. # Search Users Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/search-users GET /v1/tiktok/search/users Search TikTok users by keyword. Each request costs **5 credits**. Failed requests are not charged. # Search Videos Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/search-videos GET /v1/tiktok/search/videos Search TikTok videos by keyword. Each request costs **5 credits**. Failed requests are not charged. # Shop Bestsellers Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/shop-bestsellers GET /v1/tiktok/shop/bestsellers Sales-ranked best-selling TikTok Shop products for every operating market, ordered by real sold_count. Ranked by each product's real `sold_count` (`source: "sales_ranked"`). Omit `category_id` for a market-wide list, or pass one to rank within a category. `pages` (1-4) controls how many category pages are aggregated before ranking; `limit` (1-100) caps the returned list. **Markets** — available for every operating market: `US`, `GB`, `ID` (Tokopedia), and the Southeast Asian markets `SG`, `MY`, `PH`, `TH`, `VN` plus `JP`, each in its local currency. This is the recommended trending/best-seller endpoint for markets where TikTok exposes no curated ranking page. `region=TW` returns HTTP 200 with `availability: "not_operated"` and an empty list — TikTok operates no Shop marketplace in Taiwan. Each request costs **5 credits**. Failed requests are not charged. # Shop Root Categories Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/shop-categories GET /v1/tiktok/shop/categories The 28 top-level TikTok Shop categories of a market — drill down with the category endpoint. Returns the 28 top-level categories with their ids (shared across markets). Pass an id to [Shop Category Products](/api-reference/endpoint/tiktok/shop-category) for subcategories and top products. **Markets** — `region=US` (default) serves everything; `GB` and `ID` (Tokopedia) serve categories, category products and product detail in GBP/IDR. SG, MY, PH, TH, VN, MX, BR and JP sit behind a puzzle our exits do not clear and return `400`. Each request costs **5 credits**. Failed requests are not charged. # Shop Category Products Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/shop-category GET /v1/tiktok/shop/categories/{category_id} A TikTok Shop category's subcategories and the top products the storefront shows for it, in the market's currency. `children` are the direct subcategories (empty on a leaf), `products` the top products the storefront renders for the category (10–25). Works in `US`, `GB` and `ID`. **Markets** — `region=US` (default) serves everything; `GB` and `ID` (Tokopedia) serve categories, category products and product detail in GBP/IDR. SG, MY, PH, TH, VN, MX, BR and JP sit behind a puzzle our exits do not clear and return `400`. Each request costs **5 credits**. Failed requests are not charged. # Shop mall Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/shop-mall GET /v1/tiktok/shop/mall Browse Japan's TikTok Shop recommendations and navigation tabs without a TikTok account. Pass `region=JP` explicitly. Japan is currently available; Singapore and Malaysia mall feeds remain unavailable. [Shop search](/api-reference/endpoint/tiktok/shop-search) has separate market coverage. Start with `tab_id=0` for All. Read other tab IDs from `navigation`, then request that tab's feed. Tabs are merchandising groups, not a complete category tree or a sales ranking. For the next page, pass `next_page_token` unchanged as `page_token`, keeping the same `region` and `tab_id`. Tokens expire after 15 minutes and may expire earlier when the service or guest context changes. Restart from the first page if a token is rejected. Stop when `has_more` is false; page sizes vary. Products include their formatted `price_display` and ISO `currency`. Japan's prices are in JPY. An upstream verification failure returns an error instead of an empty successful page. Each request costs **5 credits**. Failed requests are not charged. # Shop Product Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/shop-product GET /v1/tiktok/shop/products/{product_id} Full TikTok Shop product page: description, images, real price, SKUs with stock, first reviews with totals, shop stats and TikTok's AI summary. `skus` carry per-variant `properties`, `price`, `available_quantity` and `in_stock`; `reviews` are the first few with `reviews_total` and `rating_breakdown` — page through [Shop Product Reviews](/api-reference/endpoint/tiktok/shop-reviews); `shop` carries the store's sold/follower/review counts. Where the storefront masks a promoted price the real price is filled from the detail API. Unknown ids return `404`. Works in `US`, `GB` and `ID`. **Markets** — `region=US` (default) serves everything; `GB` and `ID` (Tokopedia) serve categories, category products and product detail in GBP/IDR. SG, MY, PH, TH, VN, MX, BR and JP sit behind a puzzle our exits do not clear and return `400`. Each request costs **8 credits**. Failed requests are not charged. # Shop Product Reviews Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/shop-reviews GET /v1/tiktok/shop/products/{product_id}/reviews Paginated TikTok Shop product reviews with the total and rating breakdown; sort by recommended or recent, filter by star rating, media or verified purchase. `page`/`count` paginate (up to 50 per page); `sort=recent` for the newest; `rating=1..5`, `with_media=true` or `verified=true` narrow the set — `total` reflects the filter, `rating_breakdown` the whole product. US only. **Markets** — `region=US` (default) serves everything; `GB` and `ID` (Tokopedia) serve categories, category products and product detail in GBP/IDR. SG, MY, PH, TH, VN, MX, BR and JP sit behind a puzzle our exits do not clear and return `400`. Each request costs **5 credits**. Failed requests are not charged. # Shop Search Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/shop-search GET /v1/tiktok/shop/search Paginated keyword search over TikTok Shop products, 30 per page, with the TikTok video each listing is bound to, matching shops and related searches. **US** paginates with `offset`: pages hold 30 products, pass back `pagination.next_offset` until `has_more` is false, and the first page also carries `shops`, `related_searches`, `related_categories`, and each product's `video` (`play_count`, `like_count`, `author_name`) and `brand`. **Markets** — `region=US` (default), `GB` and `ID` (Tokopedia) are served in their local currency. The Southeast Asian markets `SG`, `MY`, `PH`, `TH`, `VN` and `JP` are now supported via native in-region signing and paginate with `pagination.next_page_token` (pass it back as `page_token`) rather than `offset`. `region=TW` returns HTTP 200 with `availability: "not_operated"` (TikTok runs no Shop marketplace in Taiwan). For a market-wide trending list, see [Shop Bestsellers](/api-reference/endpoint/tiktok/shop-bestsellers). Each request costs **5 credits**. Failed requests are not charged. # Shop Store Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/shop-store GET /v1/tiktok/shop/stores/{seller_id} A TikTok Shop store's stats and its full product catalogue, cursor-paginated up to 50 per page. `store` carries sold count, followers, rating and product count; `products` is one page of the catalogue (`count` up to 50) — pass back `next_cursor` as `cursor` until `has_more` is false. Any product's `seller.id` is the `seller_id`. US only. **Markets** — `region=US` (default) serves everything; `GB` and `ID` (Tokopedia) serve categories, category products and product detail in GBP/IDR. SG, MY, PH, TH, VN, MX, BR and JP sit behind a puzzle our exits do not clear and return `400`. Each request costs **5 credits**. Failed requests are not charged. # Trending Hashtags Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/trending-hashtags GET /v1/tiktok/trending/hashtags Trending hashtags ranked by usage (served via the on-device signer path). Trending hashtags are served via an on-device signer path and ranked by real usage (view counts and distinct-creator counts), not the deprecated Creative Center trend lists. Each request costs **5 credits**. Failed requests are not charged. This is a current discovery feed, not a historical ranking. Only US is currently supported; omit `period`. Other regions and historical periods return 422. # Trending Songs Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/trending-songs GET /v1/tiktok/trending/songs Trending songs/sounds ranked by usage (served via the on-device signer path). Trending songs are served via an on-device signer path and ranked by real usage (the mobile hot-music feed). Each request costs **5 credits**. Failed requests are not charged. This is a current discovery feed, not a historical ranking. Only US is currently supported; omit `period`. Other regions and historical periods return 422. # Trending Videos Source: https://docs.scrapebadger.com/api-reference/endpoint/tiktok/trending-videos GET /v1/tiktok/trending/videos Trending videos from the TikTok Explore feed. Each request costs **5 credits**. Failed requests are not charged. This is a current discovery feed, not a historical ranking. The mobile provider is used for US. Other regions use the web Explore fallback and may be unavailable. # Get Trending Topics Source: https://docs.scrapebadger.com/api-reference/endpoint/trends/get-trending-topics get /v1/twitter/trends/ Get current trending topics on Twitter. Results can be filtered by category: trending (default), for-you, news, sports, or entertainment. Returns trend names, tweet counts, and context information. # Get Trends by Location Source: https://docs.scrapebadger.com/api-reference/endpoint/trends/get-trends-by-location get /v1/twitter/trends/place/{woeid} Get trending topics for a specific geographic location identified by its WOEID (Where On Earth ID). Returns location-specific trends including trend names, tweet volumes, and search URLs. Use WOEID 1 for worldwide trends, or 23424977 for United States. # Advanced Tweet Search Source: https://docs.scrapebadger.com/api-reference/endpoint/tweets/advanced-search get /v1/twitter/tweets/advanced_search Search for tweets using advanced query syntax. Supports filtering by Top, Latest, or Media results. Use Twitter's advanced search operators in the query (e.g., `from:username`, `since:2024-01-01`, `min_faves:100`). Essential for monitoring, research, and content discovery. ## Choosing `query_type` | `query_type` | Behaviour | | - | - | | `Top` (default) | Algorithmic ranking — returns **more** results, surfacing popular/relevant tweets. | | `Latest` | Reverse-chronological — returns **fewer, most-recent** tweets in time order. | | `Media` | Tweets that contain media (images/video). | Use `Latest` when you need a fresh, chronological feed (e.g. monitoring), and `Top` when you want maximum coverage of relevant tweets for a query. ## Pagination Paginate with the **`cursor`** parameter. Each response includes a top-level **`next_cursor`** — pass it back as `cursor` to fetch the next page. ```python Python theme={null} resp = client.twitter.advanced_search(query="from:nasa", query_type="Latest") tweets = resp["tweets"] # Next page if resp.get("next_cursor"): page2 = client.twitter.advanced_search( query="from:nasa", query_type="Latest", cursor=resp["next_cursor"] ) ``` The response has **no `meta` field**. Pagination state lives in the top-level `next_cursor` — don't read `data["meta"]`. # Get Article Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/tweets/get-article-detail get /v1/twitter/tweets/article/{article_id} Get a Twitter Article (long-form post) by its unique ID. Returns the full article content including title, body text, cover image, and author information. Twitter Articles are long-form content published directly on the platform. # Get Community Notes Source: https://docs.scrapebadger.com/api-reference/endpoint/tweets/get-community-notes get /v1/twitter/tweets/tweet/{tweet_id}/community_notes Get community notes (formerly Birdwatch) attached to a specific tweet. Community notes provide crowd-sourced context and fact-checking for tweets. Returns note text, status, and creation date. # Get Similar Tweets Source: https://docs.scrapebadger.com/api-reference/endpoint/tweets/get-similar-tweets get /v1/twitter/tweets/tweet/{tweet_id}/similar Get tweets that are similar in content or topic to the specified tweet. Returns tweets that Twitter's algorithm considers related. Useful for content discovery and topic analysis. # Get Tweet Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/tweets/get-tweet-detail get /v1/twitter/tweets/tweet/{tweet_id} Fetch detailed information about a single tweet. Returns comprehensive tweet data including author info, engagement stats, media attachments, polls, referenced tweets, and edit history. Use this for deep inspection of individual tweets. # Get Tweet Edit History Source: https://docs.scrapebadger.com/api-reference/endpoint/tweets/get-tweet-edit-history get /v1/twitter/tweets/tweet/{tweet_id}/edit_history Get the edit history of a tweet. Returns all versions of the tweet in chronological order, from the original to the most recent edit. Useful for tracking changes to tweet content over time. # Get Tweet Favoriters Source: https://docs.scrapebadger.com/api-reference/endpoint/tweets/get-tweet-favoriters get /v1/twitter/tweets/tweet/{tweet_id}/favoriters Get the list of users who favorited (liked) a specific tweet. Returns comprehensive user profile data for each user who liked the tweet. Useful for audience analysis and engagement tracking. # Get Tweet Quotes Source: https://docs.scrapebadger.com/api-reference/endpoint/tweets/get-tweet-quotes get /v1/twitter/tweets/tweet/{tweet_id}/quotes Get tweets that quote the specified tweet. Returns comprehensive tweet data for each quote tweet including text, media, engagement metrics, and author information. Useful for tracking how a tweet is being discussed and shared. # Get Tweet Replies Source: https://docs.scrapebadger.com/api-reference/endpoint/tweets/get-tweet-replies get /v1/twitter/tweets/tweet/{tweet_id}/replies Get replies to a specific tweet. Returns comprehensive tweet data for each reply including text, media, engagement metrics, and author information. Supports pagination for tweets with many replies. # Get Tweet Retweeters Source: https://docs.scrapebadger.com/api-reference/endpoint/tweets/get-tweet-retweeters get /v1/twitter/tweets/tweet/{tweet_id}/retweeters Get the list of users who retweeted a specific tweet. Returns comprehensive user profile data for each retweeter with pagination support. Useful for analyzing tweet reach and audience engagement. # Get Tweets by IDs Source: https://docs.scrapebadger.com/api-reference/endpoint/tweets/get-tweets-by-ids get /v1/twitter/tweets/ Retrieve multiple tweets by their IDs in a single request. Returns comprehensive tweet data for each requested ID including text, media attachments, engagement metrics, and all available metadata. Useful for bulk tweet lookups and monitoring specific tweets. # Batch Get Users by IDs Source: https://docs.scrapebadger.com/api-reference/endpoint/users/batch-get-users-by-ids get /v1/twitter/users/batch_by_ids Fetch multiple user profiles by their numeric IDs in a single request. Returns comprehensive user profile data for each requested ID. More efficient than making individual requests when you need data for multiple users. # Batch Get Users by Usernames Source: https://docs.scrapebadger.com/api-reference/endpoint/users/batch-get-users-by-usernames get /v1/twitter/users/batch_by_usernames Fetch multiple user profiles by their usernames (screen names) in a single request. Returns comprehensive user profile data for each requested username. More efficient than making individual requests when you need data for multiple users. # Get User Articles Source: https://docs.scrapebadger.com/api-reference/endpoint/users/get-user-articles get /v1/twitter/users/{user_id}/articles Get long-form articles (Twitter Articles) written by a specific user. Returns article metadata including title, body text, cover image, and publication date. Requires the user's numeric ID. # Get User by ID Source: https://docs.scrapebadger.com/api-reference/endpoint/users/get-user-by-id get /v1/twitter/users/{user_id}/by_id Get a user profile by their numeric Twitter ID. Returns comprehensive profile data including bio, follower/following counts, verification status, and account metadata. Use this when you have the numeric ID and need full profile details. # Get User by Username Source: https://docs.scrapebadger.com/api-reference/endpoint/users/get-user-by-username get /v1/twitter/users/{username}/by_username Get a user profile by their username (screen name). Returns comprehensive profile data including bio, follower/following counts, verification status, and account metadata. The most common way to look up a user profile. # Get User Followers Source: https://docs.scrapebadger.com/api-reference/endpoint/users/get-user-followers get /v1/twitter/users/{username}/followers Get the list of followers for a specific user. Returns comprehensive user profile data for each follower with pagination support. Useful for audience analysis and social graph exploration. # Get User Following Source: https://docs.scrapebadger.com/api-reference/endpoint/users/get-user-following get /v1/twitter/users/{username}/followings Get the list of users that a specific user is following. Returns comprehensive user profile data for each followed account with pagination support. Useful for understanding a user's interests and network. # Get User Mentions Source: https://docs.scrapebadger.com/api-reference/endpoint/users/get-user-mentions get /v1/twitter/users/{username}/mentions Get tweets that mention a specific user. Returns tweets containing @username from the latest search results. Useful for monitoring brand mentions, tracking conversations, and reputation management. # Get User Subscriptions Source: https://docs.scrapebadger.com/api-reference/endpoint/users/get-user-subscriptions get /v1/twitter/users/{user_id}/subscriptions Get the premium account subscriptions for a specific user. Returns the list of accounts that the user subscribes to for premium content. Requires the user's numeric ID. # Get User Tweets Source: https://docs.scrapebadger.com/api-reference/endpoint/users/get-user-tweets get /v1/twitter/users/{username}/latest_tweets Get the latest tweets from a specific user's timeline. Returns comprehensive tweet data including text, media, engagement metrics, and all metadata. Supports pagination to retrieve the full tweet history. # Search Users Source: https://docs.scrapebadger.com/api-reference/endpoint/users/search-users get /v1/twitter/users/search_users Search for users by username, display name, or keywords in their bio. Returns matching user profiles with comprehensive data. Useful for finding accounts related to specific topics or interests. # Get Item Details Source: https://docs.scrapebadger.com/api-reference/endpoint/vinted/get-item-detail GET /v1/vinted/items/{item_id} Get detailed information about a Vinted item. ## Path Parameters The unique Vinted item ID. You can find this in search results or extract it from a Vinted listing URL. ## Query Parameters Vinted market where the item is listed. Must match the market the item belongs to. Examples: `fr`, `de`, `uk`, `it`, `es`, `pl`, `us` ## Response The payload is wrapped in an envelope: `item` holds the listing, `market` echoes the market it was read from. Echo of the requested market. Item ID. Item title. Full item description text. Price object: `amount` (decimal string, e.g. `"45.0"`) and `currency_code` (ISO 4217, e.g. `"EUR"`). Buyer-protection fee as a decimal string, in `price.currency_code`. `null` when the listing page doesn't quote one. Price + buyer protection as a decimal string, in `price.currency_code`. Brand name. Vinted brand ID — the value you pass to `brand_ids` on [search](/api-reference/endpoint/vinted/search-items). Vinted catalog (category) ID of the leaf category — the value you pass to `catalog_ids` on [search](/api-reference/endpoint/vinted/search-items). Category breadcrumb, root first (e.g. `["Femmes", "Vêtements", "Hauts et t-shirts", "T-shirts"]`). Localized to the market. Size label. Vinted size ID. Item condition, localized to the market (e.g. `"Très bon état"`). Vinted condition ID — see [`/v1/vinted/statuses`](/api-reference/endpoint/vinted/list-statuses). Primary color, localized. May list several, comma-separated. Secondary color (nullable). Primary photo (`id`, `url`, `full_size_url`, `width`, `height`, `dominant_color`, `is_main`). All photos, same object shape as `photo`. Full URL to the Vinted listing. Number of views. Number of favourites. Vinted's own relative "listed" label, localized (e.g. `"Il y a une semaine"`) — not an ISO timestamp. Some markets render it without a number at all (e.g. `"godziny"`), so it cannot be parsed into a date. Use `uploaded_at` instead. Approximate absolute upload time, ISO 8601 UTC (e.g. `"2026-09-23T11:28:44Z"`). Derived from the earliest photo Vinted timestamps, since Vinted exposes no creation time on the listing itself. It is approximate in both directions: a seller who replaces a photo after listing moves the stamp later, and a photo uploaded before the listing is published can predate it by about 30 minutes. `null` when Vinted stamps no photo. Search and image search responses carry no photo timestamps; mobile `catalog-search` estimates the time from the item ID instead (see [Listing age on catalog search](/vinted/mobile-api#listing-age-on-catalog-search)). Whether the item can be bought right now. Whether Buy Now is available. Whether the seller accepts bundles. Whether the item can be reserved. Whether the item is currently reserved. Whether Vinted renders the listing as no longer available (the "Sold" banner page). See [Listing states](#listing-states) — check `is_hidden` before reading this as "sold". Whether the listing is hidden by the seller (manually or via holiday mode). Hidden listings render the same "Sold" banner on Vinted — this flag is the only way to tell them apart from sold ones. `false` when the listing is hidden from the catalog (`!is_hidden`). Seller summary (`id`, `login`, `photo_url`, `business`). Richer seller record: `id`, `login`, `photo_url`, `business`, `feedback_count`, `feedback_reputation`, `item_count`, `location`, `last_seen`, `badges`. ### Listing states Every response is read live from the Vinted listing page at request time — there is no cache. The state flags combine as follows: | State | HTTP | `is_closed` | `can_buy` | `is_hidden` | `is_reserved` | | - | - | - | - | - | - | | Active | 200 | `false` | `true` | `false` | `false` | | Sold | 200 | `true` | `false` | `false` | `false` | | Hidden by seller (incl. holiday mode) | 200 | `true` | `false` | `true` | `false` | | Reserved for a buyer | 200 | — | `false` | `false` | `true` | | Deleted / withdrawn | 404 | — | — | — | — | To detect a **sale**, require `is_closed && !can_buy && !is_hidden && !is_reserved`. Vinted shows the same "Sold" banner for seller-hidden listings, so `is_closed` alone over-counts; a hidden listing can come back on the market. Listings the seller withdraws or deletes stop rendering entirely — they return a fast `404`, never a closed page. On a sold or hidden listing, `price.amount` is the seller's **asking price** (Vinted keeps showing it). The realised sale price is not present anywhere in Vinted's public payload, so we cannot expose it. ### Example Response ```json theme={null} { "item": { "id": 9492962028, "title": "Tee shirt", "description": "Tee shirt Nike noir", "price": { "amount": "1.0", "currency_code": "EUR" }, "service_fee": "0.75", "total_item_price": "1.75", "brand_title": "Nike Air", "brand_id": 5977, "catalog_id": 221, "category": ["Femmes", "Vêtements", "Hauts et t-shirts", "T-shirts", "Nike Air T-shirts"], "size_title": "S / 36 / 8", "size_id": 506, "status": "Très bon état", "status_id": 50, "color1": "Noir, Blanc", "color2": null, "photos": [ { "id": 40179825222, "url": "https://images1.vinted.net/t/...", "full_size_url": "https://images1.vinted.net/tc/...", "width": 600, "height": 800, "dominant_color": "#36363D", "is_main": true } ], "url": "https://www.vinted.fr/items/9492962028-tee-shirt", "view_count": 0, "favourite_count": 4, "upload_date": "Il y a une semaine", "can_buy": true, "instant_buy": true, "is_closed": false, "user": { "id": 20298345, "login": "majy.p", "photo_url": "https://images1.vinted.net/t/...", "business": false }, "seller": { "id": 20298345, "login": "majy.p", "business": false, "feedback_count": 356, "feedback_reputation": 1.0, "last_seen": "Vu la dernière fois : il y a une heure", "badges": ["ACTIVE_LISTER", "SPEEDY_SHIPPING"] } }, "market": "fr" } ``` Search results do **not** carry `catalog_id` or `brand_id` — Vinted's catalog endpoint doesn't return them, so they're only available here, one call per item. To narrow results by category or brand, filter at search time with `catalog_ids` / `brand_ids` instead. Each item detail request costs **10 credits**. Failed requests are not charged. The exact charge for any call is returned in the `X-Credits-Used` response header. ## Mobile item details This endpoint reads mobile JSON for the description, photos, seller and item attributes. Fields unavailable upstream remain null. In particular, size-guide FAQ IDs are not size IDs. See [mobile data](/vinted/mobile-api) for raw plugins, related items and service prices. # Get User Items Source: https://docs.scrapebadger.com/api-reference/endpoint/vinted/get-user-items GET /v1/vinted/users/{user_id}/items List all active items from a specific Vinted user. ## Path Parameters The unique Vinted user ID. ## Query Parameters Vinted market where the user is registered. Examples: `fr`, `de`, `uk`, `it`, `es`, `pl`, `us` Page number for paginated results. Starts at `1`. Number of items per page. Range: `1` - `96`. ## Response Array of items listed by the user. Item ID. Item title. Price in local currency. ISO 4217 currency code. Brand name. Size label. Primary photo with `url`, `width`, `height`. Full URL to the Vinted listing. Number of favourites. Total number of items listed by this user. Current page number. Number of items per page. ### Example Response ```json theme={null} { "items": [ { "id": 4856231890, "title": "Nike Air Force 1 '07 White", "price": "45.00", "currency": "EUR", "brand_title": "Nike", "size_title": "42", "photo": { "url": "https://images1.vinted.net/t/...", "width": 800, "height": 600 }, "url": "https://www.vinted.fr/items/4856231890", "favourite_count": 12 } ], "total_entries": 23, "current_page": 1, "per_page": 24 } ``` Each user items request costs **3 credits**. Failed requests are not charged. # Get User Profile Source: https://docs.scrapebadger.com/api-reference/endpoint/vinted/get-user-profile GET /v1/vinted/users/{user_id} Get detailed profile information for a Vinted user. ## Path Parameters The unique Vinted user ID. You can find this in search results or item detail responses. ## Query Parameters Vinted market where the user is registered. Examples: `fr`, `de`, `uk`, `it`, `es`, `pl`, `us` ## Response User ID. Username. Profile photo with `url`, `width`, `height`. Number of items the user has sold. Number of items currently listed. Number of followers. Number of users followed. Reputation score between `0` and `1`. Total number of feedback ratings received. User's city (if public). User's country. ISO 8601 timestamp of last login. ISO 8601 timestamp when the account was created. ### Example Response ```json theme={null} { "id": 12345678, "login": "seller_username", "photo": { "url": "https://images1.vinted.net/t/...", "width": 400, "height": 400 }, "given_item_count": 87, "item_count": 23, "followers_count": 156, "following_count": 42, "feedback_reputation": 0.98, "feedback_count": 74, "city": "Paris", "country_title": "France", "last_loged_on": "2026-03-29T18:00:00Z", "created_at": "2022-06-10T12:00:00Z" } ``` Each user profile request costs **3 credits**. Failed requests are not charged. # List Colors Source: https://docs.scrapebadger.com/api-reference/endpoint/vinted/list-colors GET /v1/vinted/colors List all available color filters for Vinted search. ## Query Parameters Vinted market. Color names are localized to the market language. ## Response Array of available colors. Color ID. Use this value in the `color_ids` filter when searching items. Localized color name. Hex color code (e.g. `"#000000"`). ### Example Response ```json theme={null} { "colors": [ { "id": 1, "title": "Black", "hex": "#000000" }, { "id": 3, "title": "Grey", "hex": "#808080" }, { "id": 4, "title": "White", "hex": "#FFFFFF" }, { "id": 7, "title": "Blue", "hex": "#0000FF" }, { "id": 12, "title": "Red", "hex": "#FF0000" } ] } ``` Each color list request costs **1 credit**. Failed requests are not charged. # List Markets Source: https://docs.scrapebadger.com/api-reference/endpoint/vinted/list-markets GET /v1/vinted/markets List all supported Vinted markets with their domains and country codes. ## Response Array of supported Vinted markets. Market code to use in the `market` query parameter (e.g. `"fr"`, `"de"`). Country name. Vinted domain for this market (e.g. `"vinted.fr"`). ISO 4217 currency code used in this market. ### Example Response ```json theme={null} { "markets": [ { "code": "fr", "title": "France", "domain": "vinted.fr", "currency": "EUR" }, { "code": "de", "title": "Germany", "domain": "vinted.de", "currency": "EUR" }, { "code": "uk", "title": "United Kingdom", "domain": "vinted.co.uk", "currency": "GBP" }, { "code": "us", "title": "United States", "domain": "vinted.com", "currency": "USD" } ] } ``` Each markets list request costs **0 credits** — listing markets is free. Failed requests are not charged. # List Conditions Source: https://docs.scrapebadger.com/api-reference/endpoint/vinted/list-statuses GET /v1/vinted/statuses List all available item condition statuses for Vinted search. ## Query Parameters Vinted market. Status names are localized to the market language. ## Response Array of available item conditions. Status ID. Use this value in the `status_ids` filter when searching items. Localized condition label. ### Example Response ```json theme={null} { "statuses": [ { "id": 6, "title": "New with tags" }, { "id": 1, "title": "New without tags" }, { "id": 2, "title": "Very good" }, { "id": 3, "title": "Good" }, { "id": 4, "title": "Satisfactory" } ] } ``` Each status list request costs **1 credit**. Failed requests are not charged. # List mobile operations Source: https://docs.scrapebadger.com/api-reference/endpoint/vinted/mobile-operations GET /v1/vinted/mobile/operations Discover all public Vinted mobile reads, parameter types, required fields and examples. Free. See [Vinted mobile data](/vinted/mobile-api) for the complete operation catalog. # Read mobile data Source: https://docs.scrapebadger.com/api-reference/endpoint/vinted/mobile-read POST /v1/vinted/mobile/{operation} Read public Vinted data, including sold comparables, pricing, reviews, categories and shipping references. Send `market` and operation-specific `parameters` in the JSON body. Discover operation names, types and examples with [List mobile operations](/api-reference/endpoint/vinted/mobile-operations). The response contains `operation`, `market`, and upstream JSON in `data`. Each successful read costs one credit; failed requests are free. See [Vinted mobile data](/vinted/mobile-api) for every operation and CLI/MCP examples. # Search Brands Source: https://docs.scrapebadger.com/api-reference/endpoint/vinted/search-brands GET /v1/vinted/brands Search for Vinted brand IDs by name. ## Query Parameters Brand name to search for. Partial matches are supported. Examples: `Nike`, `Adidas`, `Zara` Vinted market to search brands in. Brand availability may vary by market. ## Response Array of matching brands. Brand ID. Use this value in the `brand_ids` filter when searching items. Brand name. URL-friendly brand name. Number of users following this brand. Number of items listed under this brand. ### Example Response ```json theme={null} { "brands": [ { "id": 53, "title": "Nike", "slug": "nike", "favourite_count": 245000, "item_count": 1823456 }, { "id": 2319, "title": "Nike ACG", "slug": "nike-acg", "favourite_count": 8700, "item_count": 12340 } ] } ``` Each brand search request costs **3 credits**. Failed requests are not charged. # Search by Image Source: https://docs.scrapebadger.com/api-reference/endpoint/vinted/search-by-image POST /v1/vinted/search_by_image Supply exactly one of image_url or image_base64 (JPEG/PNG/WebP, at most 5 MiB decoded). Find active Vinted listings from a photo. 10 credits per successful request. Returns the usual items, pagination and market envelope. Visual ranking. Each item carries similarity_score (0-1; the query image's own listing scores 1.0) on the calls where Vinted returns a ranking, and null on the ones where it does not. Resend the same image and pagination time for subsequent pages. Structured brand data may be null. Find active listings from one image URL or base64 photo. See the [image-search guide](/vinted/image-search) for local files, filters and client examples. Send exactly one of `image_url` or `image_base64`. JPEG, PNG and WebP images can be up to 5 MiB decoded. Authenticate with your `x-api-key` header. # Search Items Source: https://docs.scrapebadger.com/api-reference/endpoint/vinted/search-items GET /v1/vinted/search Search Vinted catalog items with filters. ## Query Parameters Search query string. Matches against item titles and descriptions. Vinted market to search. See [`/v1/vinted/markets`](/api-reference/endpoint/vinted/list-markets) for all supported values. Examples: `fr`, `de`, `uk`, `it`, `es`, `pl`, `us` Page number for paginated results. Starts at `1`. Number of items per page. Range: `1` - `96`. Minimum price filter in the market's local currency. Maximum price filter in the market's local currency. Comma-separated list of Vinted catalog (category) IDs. Vinted applies this **before** the search runs, so you get whole pages of in-category results instead of filtering them out afterwards. A catalog ID is the `catalog[]` value in a Vinted category URL — browse to the category on the Vinted site and read it off the address bar: `vinted.fr/catalog?catalog[]=221` → `catalog_ids=221`. Sub-categories are included: `catalog_ids=221` (Women's T-shirts) also matches the brand-specific leaves beneath it. Example: `221`, `221,1242` Catalog IDs are **per market**. An ID read off `vinted.fr` is not guaranteed to mean the same category on `vinted.de` — take the ID from the same market you pass as `market`. Comma-separated list of brand IDs to filter by. Use [`/v1/vinted/brands`](/api-reference/endpoint/vinted/search-brands) to look up IDs. Example: `53`, `14,53,221` Comma-separated list of color IDs to filter by. Use [`/v1/vinted/colors`](/api-reference/endpoint/vinted/list-colors) to look up IDs. Example: `1`, `1,4,12` Comma-separated list of condition status IDs to filter by. Use [`/v1/vinted/statuses`](/api-reference/endpoint/vinted/list-statuses) to look up IDs. Example: `6` (New with tags), `1,2` (New without tags, Very good) Sort order for results. | Value | Description | | - | - | | `relevance` | Best match (default) | | `price_low_to_high` | Cheapest first | | `price_high_to_low` | Most expensive first | | `newest_first` | Most recently listed | Comma-separated list of ISO 3166-1 alpha-2 country codes (case-insensitive) to keep only items whose **seller is physically located** in one of those countries. Vinted markets federate listings across borders — a search on `vinted.fr` returns items from sellers in IT, DE, NL, ES, and elsewhere (prices and labels are localized, but the seller is abroad). Vinted exposes no native country facet, so ScrapeBadger resolves each result item's seller country and drops items outside the requested set. Examples: `fr`, `fr,be`, `IT,ES` `market` and `seller_country` are **different axes**. `market` selects which Vinted domain you search (which catalog and currency you see); `seller_country` filters on where the seller actually is. For example, `market=fr&seller_country=it` searches the French catalog but returns only items shipped by sellers in Italy. Pagination totals (`total_entries` / `total_pages`) reflect Vinted's **unfiltered** result set. After seller-country filtering, a page may contain fewer than `per_page` items (or none), even though more matching items exist on later pages. Iterate through pages until you have collected enough matching items. ## Response Array of matching items. Item ID. Item title. Price object: `amount` (decimal string, e.g. `"45.0"`) and `currency_code` (ISO 4217, e.g. `"EUR"`). Buyer-protection fee as a decimal string, in `price.currency_code`. `null` when Vinted doesn't quote one. Price + buyer protection as a decimal string, in `price.currency_code`. Brand name. Size label. Item condition, localized to the market (e.g. `"Très bon état"`). Full URL to the Vinted listing. Path portion of the listing URL. Primary photo (`id`, `url`, `full_size_url`, `width`, `height`, `dominant_color`, `is_main`). All photos, same object shape as `photo`. Seller summary (`id`, `login`, `photo_url`, `business`). Number of users who favourited this item. Number of views. Whether the listing is publicly visible. Whether the listing is a promoted/bumped placement. Vinted's own label for where the result came from (e.g. `"search"`). ISO 3166-1 alpha-2 code of the seller's physical country (e.g. `"IT"`). Populated only when `seller_country` filtering was requested; `null` otherwise. Current page number. Number of items per page. Total number of pages. Total number of matching items. Vinted caps this at 960 on deep result sets, so treat it as an upper bound rather than an exact count. Echo of the market that was searched. Echo of the normalized `seller_country` filter that was applied (uppercase, comma-separated ISO-2 codes, e.g. `"FR,BE"`), or `null` when no filter was requested. ### Example Response ```json theme={null} { "items": [ { "id": 9492962028, "title": "Nike Air Force 1 '07 White", "price": { "amount": "45.0", "currency_code": "EUR" }, "service_fee": "3.05", "total_item_price": "48.05", "brand_title": "Nike", "size_title": "42", "status": "Très bon état", "url": "https://www.vinted.fr/items/9492962028-nike-air-force-1", "path": "/items/9492962028-nike-air-force-1", "is_visible": true, "promoted": false, "favourite_count": 12, "view_count": 234, "content_source": "search", "seller_country_code": null, "user": { "id": 12345678, "login": "seller_username", "photo_url": "https://images1.vinted.net/t/...", "business": false }, "photo": { "id": 40179825222, "url": "https://images1.vinted.net/t/...", "full_size_url": "https://images1.vinted.net/tc/...", "width": 600, "height": 800, "dominant_color": "#36363D", "is_main": true }, "photos": [] } ], "pagination": { "current_page": 1, "per_page": 20, "total_pages": 48, "total_entries": 960 }, "market": "fr", "seller_country": null } ``` ### Example Request — filter by category Only women's T-shirts (`catalog[]=221` on vinted.fr): ```bash cURL theme={null} curl "https://scrapebadger.com/v1/vinted/search?query=nike&market=fr&catalog_ids=221&per_page=20" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const results = await client.vinted.search({ query: "nike", market: "fr", catalog_ids: "221", per_page: 20, }); ``` ```python Python theme={null} results = client.vinted.search( query="nike", market="fr", catalog_ids="221", per_page=20, ) ``` ### Example Request — filter by seller country Return only listings from sellers physically located in France: ```bash cURL theme={null} curl "https://scrapebadger.com/v1/vinted/search?query=nike+air+force+1&market=fr&seller_country=fr&per_page=20" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const results = await client.vinted.search({ query: "nike air force 1", market: "fr", seller_country: "fr", per_page: 20, }); ``` ```python Python theme={null} results = client.vinted.search( query="nike air force 1", market="fr", seller_country="fr", per_page=20, ) ``` A search costs **5 credits**, whatever filters you pass — including `seller_country`, whose seller lookups are not billed on top. Failed requests are not charged. The exact charge for any call is returned in the `X-Credits-Used` response header. ## Mobile search additions `size_ids` and `material_ids` accept comma-separated filter IDs. Reuse the returned pagination `time` and a shared `search_session_id` across pages. Search item `display_title` / `display_subtitle` preserve presentation labels; `brand_title` can be null. Use item details for verified brand, category and condition IDs. See [mobile data](/vinted/mobile-api). # Autocomplete Source: https://docs.scrapebadger.com/api-reference/endpoint/walmart/autocomplete GET https://scrapebadger.com/v1/walmart/autocomplete Walmart search-box suggestions for a partial term, with the department each one belongs to. Expand a partial search term into Walmart's own search-box suggestions, each tagged with the department it belongs to. Backed by Walmart's typeahead service — the cheapest call in this API. **Credits:** 1 ## Authorization Your ScrapeBadger API key. ## Query Parameters Partial search term, e.g. `lapt`. ## Response Echo of the requested query. Number of suggestions. Suggestions. The suggested search term — feed straight into `/search`. e.g. `QUERY`. Full walmart.com search URL for the suggestion. e.g. `3944` — usable as a `/category` path segment. e.g. `Electronics`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/walmart/autocomplete?query=lapt" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/walmart/autocomplete?" + new URLSearchParams({ query: "lapt" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/walmart/autocomplete", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "lapt"}, ) data = res.json() ``` ```json Response theme={null} { "query": "lapt", "result_count": 8, "suggestions": [ { "query": "laptop", "type": "QUERY", "image_url": "https://i5.walmartimages.com/asr/82b98986-afdd-40c3-a2d5-b0355110c65d.jpeg", "url": "https://www.walmart.com/search?query=laptop&typeahead=laptop", "department_id": "3944", "department_name": "Electronics" }, { "query": "laptop computers under $200", "type": "QUERY", "image_url": "https://i5.walmartimages.com/asr/043886ec-7727-46d0-aa46-432fb2e614b3.jpeg", "url": "https://www.walmart.com/search?query=laptop%20computers%20under%20%24200&typeahead=laptop", "department_id": "3944", "department_name": "Electronics" }, { "query": "laptop resold", "type": "QUERY", "image_url": "https://i5.walmartimages.com/dfw/63fd9f59-d78b/glass_icon.png", "url": "https://www.walmart.com/search?query=laptop%20resold&typeahead=laptop", "department_id": null, "department_name": null } ] } ``` Because [`/search`](/api-reference/endpoint/walmart/search) hits a hard page-10 wall, fanning one term out into several suggested queries and merging the results on `us_item_id` buys wider coverage than paging deeper — at 1 credit per expansion. # Browse a Category Source: https://docs.scrapebadger.com/api-reference/endpoint/walmart/category GET https://scrapebadger.com/v1/walmart/category Browse any walmart.com category or department path — same result shape as search. Browse a Walmart category by its browse path. Returns the same `SearchResponse` shape as [`/search`](/api-reference/endpoint/walmart/search). **Credits:** 5 **No `sort` parameter.** Walmart's browse pages ignore it — sorted and unsorted requests returned 34/38 identical item ids with identical leading results, and Walmart does not echo the parameter back. Sort on [`/search`](/api-reference/endpoint/walmart/search) instead. ## Authorization Your ScrapeBadger API key. ## Query Parameters Walmart browse path, e.g. `electronics/3944` (taken from a `walmart.com/browse/...` URL), or a `/cp/...` department path. Result page, `1`–`11`. Browse dries up after page 11. Minimum price in USD. Maximum price in USD. Walmart facet filter, e.g. `brand:HP`. Facets can be applied but not enumerated. ## Response Identical to [`/search`](/api-reference/endpoint/walmart/search#response): `query` (null here), `url`, `page`, `total_results_reported`, `max_page` (`11`), `result_count`, `has_more_pages`, `title`, `breadcrumbs`, `related_searches`, and `items[]` of `SearchItem`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/walmart/category?path=electronics/3944&min_price=100" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/walmart/category?" + new URLSearchParams({ path: "electronics/3944", min_price: "100" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/walmart/category", headers={"X-API-Key": "YOUR_API_KEY"}, params={"path": "electronics/3944", "min_price": 100}, ) data = res.json() ``` ```json Response theme={null} { "query": null, "url": "https://www.walmart.com/browse/electronics/3944", "page": 1, "total_results_reported": 900010, "max_page": 11, "result_count": 49, "has_more_pages": true, "sort": null, "title": "Results for \"Electronics\"", "breadcrumbs": [ { "name": "Electronics", "url": "https://www.walmart.com/cp/3944" } ], "related_searches": [], "items": [ { "us_item_id": "5689919121", "name": "AirPods Pro (2nd generation) with MagSafe Case (USB-C)", "brand": "Apple", "url": "https://www.walmart.com/ip/AirPods-Pro-2nd-generation.../5689919121", "price": 199.0, "price_string": "$199.00", "rating": 4.4, "review_count": 44427, "in_stock": true, "availability_status": "IN_STOCK", "fulfillment_type": "FC", "seller_name": "Walmart.com", "is_sponsored": false, "position": 1 } ] } ``` `total_results_reported` is Walmart's own claim (900,010 above) and is **not reachable** — browse stops returning products after page 11, roughly 500 products. Page on `has_more_pages`, and deduplicate on `us_item_id`: consecutive pages overlap by about 20% because Walmart re-ranks between requests. Segment by `facet` or price band to go deeper. # Deals Source: https://docs.scrapebadger.com/api-reference/endpoint/walmart/deals GET https://scrapebadger.com/v1/walmart/deals Walmart's current deals, rollbacks and clearance as a paginated product feed. Walmart's live deals, rollbacks and clearance. Same result shape as [`/search`](/api-reference/endpoint/walmart/search). **Credits:** 5 No surveyed competitor offers a Walmart deals feed — every one of them exposes `rollback` only as a boolean on a product row. ## Authorization Your ScrapeBadger API key. ## Query Parameters Result page, `1`–`11`. The feed dries up after page 11. Minimum price in USD. Maximum price in USD. ## Response Identical to [`/search`](/api-reference/endpoint/walmart/search#response): `url`, `page`, `total_results_reported`, `max_page` (`11`), `result_count`, `has_more_pages`, `title`, and `items[]` of `SearchItem`. Discounted items carry `was_price` and a populated `price_info.savings_amount`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/walmart/deals?min_price=25&max_price=100" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/walmart/deals?" + new URLSearchParams({ min_price: "25", max_price: "100" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/walmart/deals", headers={"X-API-Key": "YOUR_API_KEY"}, params={"min_price": 25, "max_price": 100}, ) data = res.json() ``` ```json Response theme={null} { "query": null, "url": "https://www.walmart.com/shop/deals", "page": 1, "total_results_reported": 2054, "max_page": 11, "result_count": 50, "has_more_pages": true, "title": "Savings", "items": [ { "us_item_id": "43786351", "item_id": "43786351", "product_id": "39714L09OKKY", "offer_id": "14EFE996F12E4C8B950E542CDDBB24D0", "name": "Allegra Adult 24-Hour Allergy Relief Tablets, 180 mg Fexofenadine HCI, 40-Count", "brand": "Allegra", "url": "https://www.walmart.com/ip/Allegra-24-Hour-Allergy-Tablets-40-Ct/43786351", "image_url": "https://i5.walmartimages.com/seo/Allegra-24-Hour-Allergy-Tablets-40-Ct....jpeg", "price": 29.97, "price_string": "$29.97", "was_price": 41.98, "price_info": { "current_price": { "price": 29.97, "price_string": "$29.97", "price_display": "Now $29.97" }, "was_price": { "price": 41.98, "price_string": "$41.98" }, "savings_amount": 12.01, "is_price_reduced": true }, "rating": 4.7, "review_count": 1893, "in_stock": true, "availability_status": "IN_STOCK", "seller_name": "Walmart.com", "badges": [{ "id": "L1600", "text": "Rollback", "type": "flag", "key": "PRICE_FLAG" }], "position": 1 } ] } ``` `total_results_reported` is Walmart's own claim and is **not reachable** — the feed stops after page 11. Page on `has_more_pages`, and deduplicate on `us_item_id`: consecutive pages overlap by about 20%. Narrow with `min_price` / `max_price` bands to pull more of the feed. # Get Product Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/walmart/get-product GET https://scrapebadger.com/v1/walmart/products/{item_id} Full Walmart product detail — UPC/GTIN, structured specifications, variants, condition offers, per-fulfilment delivery dates, seller and a reviews sample. Fetch a single Walmart product by its `usItemId`. Returns everything Walmart's page carries: identifiers (`upc`, `gtin`, `model`), the full price block, per-fulfilment promised delivery dates, grouped specifications, variants, alternative condition offers, the marketplace seller, return policy, and a reviews sample with the complete star histogram. **Credits:** 10 ## Authorization Your ScrapeBadger API key. ## Path Parameters Walmart `usItemId`, e.g. `5689919121`. Take it from `us_item_id` on a search result, or from a `walmart.com/ip/.../{item_id}` URL — the SEO slug is decorative and only the numeric id is needed. ## Response The full `Product`. Key fields: e.g. `195949704529`. Manufacturer model, e.g. `MTJV3AM/A`. Walmart's own generative-AI product description, an HTML `
    `. Walmart's AI concise summary — `name`, `value`, `icon_url`. `name`, `url`. `id`, `url`, `zoomable`. `title`, `poster`, `versions`, `captions`. `current_price`, `was_price`, `list_price`, `unit_price`, `comparison_price`, `subscription_price`, `shipping_price`, `price_range`, `savings_amount`, `savings_string`, `is_price_reduced`, `additional_fees[]`, `volume_price_tiers[]`. `id`, `type`, `description`, `terms`. e.g. `IN_STOCK`. e.g. `FC`, `MARKETPLACE`. Live availability per method — `type`, `availability_status`, `available_quantity`, `is_low_in_stock`, `location_text`, `max_order_quantity`. Per-method SLA and **promised delivery dates** — `fulfillment`, `fulfillment_price`, `delivery_date`, `max_delivery_date`, `store_delivery_date`, `store_id`, `store_timezone`, `sla`, `calculated_sla_days`, `is_express`, `is_free_for_wplus`. `sla` is a structured object (`unitOfMeasure`, `minimumValue`, `maximumValue`, `rank`), not a string. Which store Walmart resolved this response against — `postal_code`, `city`, `state`, `store_id`, `intent`. `seller_id` (32-char hex), **`catalog_seller_id`** (the numeric id the seller endpoints take), `seller_name`, `seller_display_name`, `seller_type`, `seller_storefront_url`, `seller_average_rating`, `seller_review_count`, `is_pro_seller`, `wfs_enabled`. New / refurbished / pre-owned offers on the same product — `offer_id`, `condition`, `is_condition_new`, `availability_status`, `price`, `price_string`. `us_item_id`, `name`, `variant_type`, `value`, `url`, `price`, `in_stock`, `selected`, `image_url`, `swatch_image_url`. Flat spec rows — `name`, `value`. `group_name`, `specifications[]`. `information`, `length`, `url`. Grocery only — `calorie_info`, `key_nutrients`, `vitamin_minerals`, `serving_info`. `id`, `text`, `type`, `key`. `returnable`, `returnable_to_store`, `free_returns`, `return_window`, `return_policy_type`, `return_policy_text`, `return_location`. The full star histogram — counts **and** percentages. See [Get Reviews](/api-reference/endpoint/walmart/get-reviews). Saves a second call for shallow use cases. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/walmart/products/5689919121" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/walmart/products/5689919121", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const product = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/walmart/products/5689919121", headers={"X-API-Key": "YOUR_API_KEY"}, ) product = res.json() ``` ```json Response theme={null} { "us_item_id": "5689919121", "item_id": "5689919121", "product_id": "3RZ5BTN0KR6U", "offer_id": "452655F40DF73F6BA4D060C9B1C4C70A", "upc": "195949704529", "gtin": "195949704529", "model": "MTJV3AM/A", "name": "Apple AirPods Pro, Wireless Earbuds with MagSafe Case (USB-C), (2nd Generation), White", "brand": "Apple", "url": "https://www.walmart.com/ip/AirPods-Pro-2nd-generation-with-MagSafe-Case-USB-C/5689919121", "category_path": "0:6163033:2795380:4874644", "breadcrumbs": [ { "name": "Electronics", "url": "https://www.walmart.com/cp/3944" }, { "name": "Headphones", "url": "https://www.walmart.com/browse/3944/1095199" } ], "image_url": "https://i5.walmartimages.com/asr/f90de61f-f25c-4f57-89ef-3fd9ce4c9ed5.jpeg", "price": 82.8, "currency": "USD", "price_info": { "current_price": { "price": 82.8, "currency": "USD", "price_string": "$82.80", "price_display": "Now $82.80" }, "was_price": { "price": 184.79, "currency": "USD", "price_string": "$184.79" }, "savings_amount": 101.99, "is_price_reduced": true }, "availability_status": "IN_STOCK", "in_stock": true, "fulfillment_type": "MARKETPLACE", "fulfillment_summary": [ { "fulfillment": "DELIVERY", "fulfillment_price": 0.0, "fulfillment_methods": ["UNSCHEDULED"], "delivery_date": "2026-08-13T21:59:00.000Z", "max_delivery_date": "2026-08-13T21:59:00.000Z", "store_delivery_date": "2026-08-13T14:59:00.000-07:00", "store_timezone": "America/Los_Angeles", "sla": { "unitOfMeasure": "DAYS", "minimumValue": 3, "maximumValue": 5, "rank": 2 }, "calculated_sla_days": 5, "is_express": false } ], "location": { "postal_code": "95519", "city": "Mckinleyville", "state": "CA", "store_id": "5629", "intent": "SHIPPING" }, "rating": 4.4, "review_count": 44427, "seller": { "seller_id": "66656029CC6541CBADDFA17547A98DE0", "catalog_seller_id": "152", "seller_name": "VIPOUTLET", "seller_type": "EXTERNAL", "seller_storefront_url": "https://www.walmart.com/global/seller/152", "seller_average_rating": 3.97, "seller_review_count": 12043, "is_pro_seller": true }, "condition": "Pre-Owned: Fair", "condition_offers": [ { "offer_id": "9DF22736171B3DCD8FAC29C7E1D80EDA", "condition": "New", "is_condition_new": true, "availability_status": "OUT_OF_STOCK", "price": 199.0, "price_string": "$199.00" }, { "offer_id": "452655F40DF73F6BA4D060C9B1C4C70A", "condition": "Pre-Owned: Fair", "is_condition_new": false, "availability_status": "IN_STOCK", "price": 82.8, "price_string": "$82.80" } ], "specifications": [ { "name": "Noise control technology", "value": "Active Noise Cancellation" }, { "name": "Battery life", "value": "6 h" }, { "name": "Works with", "value": "iPhone, iPad, Mac" }, { "name": "Ip code", "value": "IPX4" } ], "ai_description_html": "
    • Product Identity: White Apple AirPods Pro (2nd Generation) in-ear wireless earbuds…
    ", "ai_highlights": [ { "name": "Adaptive Noise Control", "value": "Adaptive Audio that tailors noise control.", "icon_url": "https://i5.walmartimages.com/dfw/84bce68-1bf3/adaptive.png" } ], "badges": [ { "id": "L1095", "text": "Pre-Owned: Fair", "type": "product_condition", "key": "PREOWNED" }, { "id": "L1071", "text": null, "type": "urgency", "key": "LOW_INVENTORY" } ], "return_policy": { "returnable": true, "returnable_to_store": true, "free_returns": true, "return_policy_type": "seamless", "return_policy_text": "Free 30-day returns", "return_location": "store" }, "rating_distribution": { "average_rating": 4.4, "total_review_count": 44427, "five_star": 34522, "five_star_percent": 78, "one_star": 4312, "one_star_percent": 10 } } ``` Prices and availability are **store-specific**. Walmart resolves the assortment store from the request IP and overwrites any store id you try to set, so it cannot be pinned by a parameter. The `location` block names the store that actually answered — always read it before comparing prices across calls. To reach the seller endpoints, use **`seller.catalog_seller_id`** (numeric, `152` above) — not `seller.seller_id`, which is a 32-char hex value and 404s as a storefront URL. ## Errors | Status | Meaning | | - | - | | `404` | Item does not exist or has been removed. | | `422` | Anti-bot challenge — **not billed**. Retry; it succeeds. | # Get Product Reviews Source: https://docs.scrapebadger.com/api-reference/endpoint/walmart/get-reviews GET https://scrapebadger.com/v1/walmart/products/{item_id}/reviews Paginated Walmart customer reviews with the complete star histogram — counts and percentages. Paginated customer reviews for a product, plus the **full rating distribution**: per-star counts *and* percentages, recommended percentage, media count, review aspects, and the most-helpful positive and negative reviews. **Credits:** 10 **10 reviews per page.** That is Walmart's page size and is not adjustable. ## Authorization Your ScrapeBadger API key. ## Path Parameters Walmart `usItemId`, e.g. `5689919121`. ## Query Parameters Review page, `1`–`100`. 10 reviews per page. Review ordering. One of `relevancy`, `submission-desc`, `submission-asc`, `rating-desc`, `rating-asc`, `helpful`. ## Response Echo of the requested item id. The walmart.com URL that was fetched. Reviews on this page (10 on a full page). The complete star histogram. Reviews carrying written text — the rest are ratings only. Walmart's per-aspect sentiment breakdown, where present. Walmart's AI review summary, where present. Most-helpful positive review. Most-helpful negative review. Reviews on this page. ISO 8601 UTC. Unix seconds. e.g. `Verified Purchase`, `Incentivized Review`. Seller/brand replies. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/walmart/products/5689919121/reviews?sort=helpful" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/walmart/products/5689919121/reviews?" + new URLSearchParams({ sort: "helpful" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/walmart/products/5689919121/reviews", headers={"X-API-Key": "YOUR_API_KEY"}, params={"sort": "helpful"}, ) data = res.json() ``` ```json Response theme={null} { "item_id": "5689919121", "url": "https://www.walmart.com/reviews/product/5689919121?sort=helpful", "page": 1, "sort": "helpful", "result_count": 10, "distribution": { "average_rating": 4.4, "rounded_average_rating": 4.4, "total_review_count": 44427, "reviews_with_text_count": 7540, "recommended_percentage": 86, "total_media_count": 564, "one_star": 4312, "two_star": 950, "three_star": 1399, "four_star": 3244, "five_star": 34522, "one_star_percent": 10, "two_star_percent": 2, "three_star_percent": 3, "four_star_percent": 7, "five_star_percent": 78 }, "aspects": [], "review_summary": null, "reviews": [ { "review_id": "393133004", "rating": 5, "title": null, "text": "The air pods are air pods. When I first went to the website a discount of $70 was indicated…", "author": "WalmartCustomer", "submitted_at": "2025-07-24T00:00:00Z", "submitted_utc": 1753315200.0, "verified_purchase": true, "helpful_count": 4, "not_helpful_count": 0, "badges": [ { "id": "VerifiedPurchaser", "text": "Verified Purchase", "type": "Custom", "key": "REVIEW" }, { "id": "PrizeIncentive", "text": "Incentivized Review", "type": "Custom", "key": "REVIEW" } ], "seller_name": "Walmart.com", "original_language": "English" } ] } ``` `total_review_count` counts every rating, while `reviews_with_text_count` counts only reviews with written text — in the example above, 44,427 ratings but 7,540 with prose. Size a full crawl off `reviews_with_text_count / 10` pages, not the headline count. ## Errors | Status | Meaning | | - | - | | `404` | Item does not exist or has been removed. | | `422` | Anti-bot challenge — **not billed**. Retry; it succeeds. | # Get Seller Profile Source: https://docs.scrapebadger.com/api-reference/endpoint/walmart/get-seller GET https://scrapebadger.com/v1/walmart/sellers/{seller_id} A Walmart marketplace seller's profile — contact details, address, rating and policies. Fetch a Walmart marketplace seller's profile: display name, business contact details and address, rating, badges and policies. **Credits:** 5 **This endpoint returns no product list.** Walmart renders storefront grids client-side (`searchResult` comes back as `{isEmptySearchResult: true}` for every seller tested), and adding `?page=` makes Walmart's own server-side render throw. Use [`/sellers/{seller_id}/products`](/api-reference/endpoint/walmart/get-seller-products) for the catalogue. ## Authorization Your ScrapeBadger API key. ## Path Parameters **Numeric catalog seller id**, e.g. `6907`. This is `seller.catalog_seller_id` on a [product](/api-reference/endpoint/walmart/get-product) — **not** the 32-char hex `seller.seller_id`, which 404s as a storefront URL. ## Response The seller profile. Walmart's 32-char hex seller id. The numeric id this endpoint takes. e.g. `EXTERNAL` for marketplace sellers. e.g. `ACTIVE`. Any items Walmart server-rendered on the storefront. Usually empty — the grid is client-side. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/walmart/sellers/101040442" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/walmart/sellers/101040442", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { seller } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/walmart/sellers/101040442", headers={"X-API-Key": "YOUR_API_KEY"}, ) seller = res.json()["seller"] ``` ```json Response theme={null} { "seller": { "seller_id": "8828868EF163431A961A65A6F76FA620", "catalog_seller_id": "101040442", "name": "4th Quarter Collectibles", "display_name": "4th Quarter Collectibles & Toys", "seller_type": "EXTERNAL", "url": "https://www.walmart.com/seller/8828868EF163431A961A65A6F76FA620", "logo_url": null, "banner_url": null, "about": "Toys and collectibles store.", "email": "4thqtrcollectibles@gmail.com", "phone": "8594468261", "address1": "Stella Ave", "address2": "", "city": "Cincinnati", "state": "OH", "postal_code": "45224", "country": "US", "country_code": "+1", "rating": 0.0, "review_count": 0, "has_seller_badge": false, "is_pro_seller": false, "is_alcohol_seller": false, "deactivation_status": "ACTIVE", "tax_policy": null }, "featured_items": [] } ``` ## Errors | Status | Meaning | | - | - | | `404` | Seller does not exist — most often because a hex `seller_id` was passed instead of the numeric `catalog_seller_id`. | | `422` | Anti-bot challenge — **not billed**. Retry; it succeeds. | # Get Seller Products Source: https://docs.scrapebadger.com/api-reference/endpoint/walmart/get-seller-products GET https://scrapebadger.com/v1/walmart/sellers/{seller_id}/products A Walmart marketplace seller's catalogue, scoped by a required search term. List a marketplace seller's inventory. Returns the same `SearchResponse` shape as [`/search`](/api-reference/endpoint/walmart/search). **Credits:** 5 **`query` is required.** The seller storefront renders its grid client-side, so this endpoint goes through Walmart search with a `retailer_id` facet — and that facet returns zero results with no query term. Scope the catalogue with a term (`camera`, `laptop`, a brand …) and repeat across terms to enumerate a seller. No surveyed competitor offers Walmart seller inventory at all — the seller endpoints elsewhere are profile metadata only. ## Authorization Your ScrapeBadger API key. ## Path Parameters **Numeric catalog seller id**, e.g. `6907` (Adorama). This is `seller.catalog_seller_id` on a [product](/api-reference/endpoint/walmart/get-product) — **not** the 32-char hex `seller.seller_id`. ## Query Parameters Search term scoping the seller's catalogue, e.g. `camera`. Result page, `1`–`10`. Result ordering. One of `best_match`, `best_seller`, `price_low`, `price_high`, `rating_high`, `new`. ## Response Identical to [`/search`](/api-reference/endpoint/walmart/search#response): `query`, `url`, `page`, `total_results_reported`, `max_page` (`10`), `result_count`, `has_more_pages`, `sort`, `title`, and `items[]` of `SearchItem`. Every item carries the seller's `seller_id` / `seller_name`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/walmart/sellers/6907/products?query=camera&sort=price_high" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/walmart/sellers/6907/products?" + new URLSearchParams({ query: "camera", sort: "price_high" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/walmart/sellers/6907/products", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "camera", "sort": "price_high"}, ) data = res.json() ``` ```json Response theme={null} { "query": "camera", "url": "https://www.walmart.com/search?q=camera&facet=retailer_id%3A6907", "page": 1, "total_results_reported": 658, "max_page": 10, "result_count": 42, "has_more_pages": true, "sort": "price_high", "title": "Results for \"camera\"", "items": [ { "us_item_id": "3988246008", "name": "Sony Alpha a7R V 61.0MP Full Frame Mirrorless Digital Camera Body - Bundle with 128GB SDXC Card, Backpack, Extra Battery", "brand": "Sony", "url": "https://www.walmart.com/ip/Sony-Alpha-a7R-V.../3988246008", "price": 3498.0, "price_string": "$3,498.00", "rating": 5.0, "review_count": 5, "in_stock": true, "availability_status": "IN_STOCK", "fulfillment_type": "MARKETPLACE", "seller_id": "1F94731C2621441B90812CB343D18B39", "seller_name": "Adorama", "is_sponsored": false, "position": 1 } ] } ``` Same page ceiling as search: results stop after **page 10**, and consecutive pages **overlap by roughly 20%** — deduplicate on `us_item_id`. To enumerate a large seller, run several query terms rather than paging one term deeper. ## Errors | Status | Meaning | | - | - | | `404` | Seller does not exist — check you passed the numeric `catalog_seller_id`. | | `422` | Anti-bot challenge — **not billed**. Retry; it succeeds. | # Get Store Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/walmart/get-store GET https://scrapebadger.com/v1/walmart/stores/{store_id} A physical Walmart store — address, geo, hours, per-department services with their own hours and phone, fuel prices, and ~30 nearby stores. Fetch a physical Walmart store by its store number. One call returns the store's address, geo, phone and opening hours, its **per-department services — each with its own phone and hours** — fuel prices where the store has a station, and roughly **30 nearby stores** in the same shape. **Credits:** 5 No surveyed competitor offers a Walmart store-detail endpoint at all. ## Authorization Your ScrapeBadger API key. ## Path Parameters Walmart store number, e.g. `100`. ## Response The store. e.g. `Walmart Supercenter`. e.g. `Bentonville S Walton Blvd Supercenter`. Populated on `nearby_stores`. `day`, `start`, `end`, `closed`. In-store departments — `name`, `display_name`, **`phone`**, `open_24_hours`, and their **own** `hours[]`, which differ from the store's. Department names carried by this store. Populated only for stores with a fuel station. Number of nearby stores returned (\~30). Nearby stores, same `Store` shape, each with `distance_miles`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/walmart/stores/100" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch("https://scrapebadger.com/v1/walmart/stores/100", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY }, }); const { store, nearby_stores } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/walmart/stores/100", headers={"X-API-Key": "YOUR_API_KEY"}, ) store = res.json()["store"] ``` ```json Response theme={null} { "store": { "store_id": "100", "name": "Walmart Supercenter", "display_name": "Bentonville S Walton Blvd Supercenter", "store_type": "STORE", "phone": "479-273-0060", "address1": "406 S Walton Blvd", "address2": null, "city": "Bentonville", "state": "AR", "postal_code": "72712", "country": "US", "latitude": 36.368173, "longitude": -94.224844, "open_24_hours": false, "is_spark_store": false, "is_glass_eligible": true, "hours": [ { "day": "Sunday", "start": "06:00", "end": "23:00", "closed": false }, { "day": "Monday", "start": "06:00", "end": "23:00", "closed": false } ], "services": [ { "name": "DELI", "display_name": "Deli", "phone": "479-273-5780", "open_24_hours": false, "hours": [{ "day": "Sunday", "start": "08:00", "end": "21:00", "closed": false }] }, { "name": "PHARMACY", "display_name": "Pharmacy", "phone": "479-273-5080", "open_24_hours": false, "hours": [{ "day": "Sunday", "start": "10:00", "end": "18:00", "closed": false }] } ], "access_types": ["PICKUP", "DELIVERY"] }, "departments": [ "Furniture", "Hardware", "Fashion", "Electronics", "Toys", "Patio & Garden", "Video Game Store", "Computer Store" ], "fuel_prices": [], "nearby_count": 33, "nearby_stores": [ { "store_id": "5260", "name": "Walmart Neighborhood Market", "display_name": "Bentonville Neighborhood Market", "city": "Bentonville", "state": "AR", "postal_code": "72712", "latitude": 36.3492, "longitude": -94.2035, "distance_miles": 1.8, "phone": "479-464-9273" } ] } ``` Each department in `services[]` carries its **own** phone and hours — the pharmacy above opens four hours after the store does. Read department hours from `services[]`, never from the store's `hours[]`. ## Errors | Status | Meaning | | - | - | | `404` | Store does not exist or has closed. | | `422` | Anti-bot challenge — **not billed**. Retry; it succeeds. | # List Markets Source: https://docs.scrapebadger.com/api-reference/endpoint/walmart/list-markets GET https://scrapebadger.com/v1/walmart/markets List the supported Walmart markets. US only. List the supported Walmart markets. This endpoint is **free**. **Credits:** 0 **Only `walmart.com` (US) is supported.** `walmart.ca` and `walmart.com.mx` run on different platforms with different payload shapes — they are not a locale switch on walmart.com, and are deliberately not claimed here rather than shipped broken. ## Authorization Your ScrapeBadger API key. ## Response Number of markets. Supported markets. e.g. `US`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/walmart/markets" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch("https://scrapebadger.com/v1/walmart/markets", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY }, }); const { markets } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/walmart/markets", headers={"X-API-Key": "YOUR_API_KEY"}, ) markets = res.json()["markets"] ``` ```json Response theme={null} { "result_count": 1, "markets": [ { "code": "US", "name": "United States", "domain": "walmart.com", "currency": "USD", "language": "en-US" } ] } ``` # Search Products Source: https://docs.scrapebadger.com/api-reference/endpoint/walmart/search GET https://scrapebadger.com/v1/walmart/search Search walmart.com by keyword with sort, price band and facet filters. Search `walmart.com` for products. Returns \~40–60 organic products per page. Sponsored ad tiles are dropped; sponsored *products* are returned and flagged `is_sponsored`. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `laptop`. Result page, `1`–`10`. Results dry up after page 10 — see [Pagination](#pagination). Result ordering. One of `best_match`, `best_seller`, `price_low`, `price_high`, `rating_high`, `new`. Minimum price in USD. Maximum price in USD. Walmart facet filter, e.g. `brand:HP`. Facets can be **applied but not enumerated** — Walmart renders the filter rail client-side, so there is no endpoint that lists them. ## Response Echo of the requested query. The walmart.com URL that was fetched. The page returned. **Walmart's own claim**, not a reachable count — it reports \~14,700 for a query that stops returning products after page 10. It moves correctly when a filter is applied, so it is a useful *relative* signal only. Measured page ceiling for this surface (`10` for search). Products on this page. Page on this, not on `total_results_reported`. The sort that was applied. Walmart's result heading, e.g. `Results for "laptop"`. `name`, `url`. Walmart's related query suggestions. Set when Walmart corrected the query. Product cards. Walmart's item id — use it for `/products/{item_id}` and to deduplicate. Full price block — `current_price`, `was_price`, `price_range`, `savings_amount`. e.g. `IN_STOCK`, `OUT_OF_STOCK`. e.g. `FC`, `MARKETPLACE`. `id`, `text`, `type`, `key`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/walmart/search?query=laptop&sort=price_low&max_price=500" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/walmart/search?" + new URLSearchParams({ query: "laptop", sort: "price_low", max_price: "500", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/walmart/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "query": "laptop", "sort": "price_low", "max_price": 500, }, ) data = res.json() ``` ```json Response theme={null} { "query": "laptop", "url": "https://www.walmart.com/search?q=laptop", "page": 1, "total_results_reported": 14714, "max_page": 10, "result_count": 52, "has_more_pages": true, "sort": null, "title": "Results for \"laptop\"", "breadcrumbs": [{ "name": "laptop", "url": null }], "related_searches": ["hp laptop", "macbook", "gaming laptop", "chromebook"], "spelling_correction": null, "items": [ { "us_item_id": "20353606354", "item_id": "20353606354", "product_id": "4W9K25QVD1IR", "offer_id": "CFD877430F6D3E37B5678F4880EC10C8", "name": "HP Essential 14\" Laptop, Intel N150, 8GB RAM, 128GB eMMC, Windows 11 Home, Pink", "brand": "HP", "url": "https://www.walmart.com/ip/HP-Essential-14-Laptop.../20353606354", "image_url": "https://i5.walmartimages.com/seo/HP-Essential-14-Laptop....jpeg", "price": 298.96, "price_string": "$298.96", "price_info": { "current_price": { "price": 298.96, "price_string": "$298.96", "price_display": "$298.96" }, "price_range": { "min_price": 269.0, "price_string": "Options from $269.00" }, "savings_amount": 0.0 }, "rating": 4.0, "review_count": 4, "in_stock": true, "is_out_of_stock": false, "availability_status": "IN_STOCK", "fulfillment_type": "FC", "fulfillment_badges": ["Free shipping, arrives in 3+ days"], "seller_id": "E3AC3CCD80E94D77A876ADE3B17D7B89", "seller_name": "PCOnline US", "is_sponsored": true, "is_two_day_shipping": false, "badges": [{ "id": "L1600", "text": "Best seller", "type": "flag", "key": "BEST_SELLER" }], "position": 1 } ] } ``` ## Pagination `total_results_reported` is not reachable. Search dries up after **page 10** — roughly **500 products per query**. Page on `has_more_pages`; page 11 returns HTTP 200 with `result_count: 0`. Consecutive pages **overlap by roughly 20%** — Walmart re-ranks between requests. **Deduplicate on `us_item_id`.** To collect more than \~500 products for a term, segment the query rather than paging deeper: repeat it per brand (`facet=brand:HP`) or across price bands (`min_price` / `max_price`). **Searching by UPC does not work** — Walmart returns zero results for a bare UPC. Search by keyword and read `upc` off [`/products/{item_id}`](/api-reference/endpoint/walmart/get-product) instead. Prices and availability are **store-specific**, resolved from the request IP and not pinnable by parameter. Fetch a product to see which store answered (its `location` block). # Detect Protection Source: https://docs.scrapebadger.com/api-reference/endpoint/web-scraping/detect POST /v1/web/detect Analyze a URL for anti-bot and CAPTCHA systems without performing a full scrape. Quickly scan a URL to identify which anti-bot and CAPTCHA systems are in use. Results are cached per domain for 5 minutes — cached hits cost **0 credits**. ## Request Body The URL to analyze for anti-bot and CAPTCHA protection systems. Must be a valid HTTP or HTTPS URL. Request timeout in milliseconds. Range: `1000` – `60000`. ISO 3166-1 alpha-2 country code for proxy geo-targeting. Some sites show different protection depending on the visitor's location. ```json theme={null} { "country": "US" } ``` ## Response The analyzed URL. List of anti-bot systems detected on the page. System name. Common values: `cloudflare_turnstile`, `datadome`, `akamai`, `kasada`, `amazon_waf`, `imperva`, `perimeterx`. Confidence score from `0.0` to `1.0`. Additional detection details. List of CAPTCHA systems detected on the page. System name. Common values: `recaptcha_v2`, `recaptcha_v3`, `hcaptcha`, `geetest`. Confidence score from `0.0` to `1.0`. Additional detection details. Whether the page is currently showing a blocking/challenge page. Type of blocking detected (e.g., `cloudflare`, `datadome`). `null` if not blocked. Suggested scraping strategy based on the detected protection. For example: `"Use browser engine with anti_bot enabled"`. Credits charged for this request. `1` for a fresh scan, `0` for a cached result. Response time in milliseconds. ## Examples ### Basic detection ```bash cURL theme={null} curl -X POST "https://scrapebadger.com/v1/web/detect" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://scrapebadger.com"}' ``` ```python Python theme={null} import requests response = requests.post( "https://scrapebadger.com/v1/web/detect", headers={"x-api-key": "YOUR_API_KEY"}, json={"url": "https://scrapebadger.com"} ) detection = response.json() for system in detection["antibot_systems"]: print(f"{system['system']}: {system['confidence']}") ``` ```javascript JavaScript theme={null} const res = await fetch("https://scrapebadger.com/v1/web/detect", { method: "POST", headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ url: "https://scrapebadger.com" }) }); const detection = await res.json(); console.log(detection.antibot_systems); ``` ### Detect with geo-targeting ```json theme={null} { "url": "https://region-restricted-site.com", "country": "DE", "timeout": 20000 } ``` ## Error Responses | Status | Description | | - | - | | `400` | Invalid URL | | `402` | Insufficient credits | | `429` | Rate limit exceeded | | `500` | Unexpected server error | ```json 200 — Protection Detected theme={null} { "url": "https://protected-site.com", "antibot_systems": [ { "system": "cloudflare_turnstile", "confidence": 0.92, "details": "Turnstile widget detected in page HTML" } ], "captcha_systems": [], "is_blocked": true, "blocking_type": "cloudflare", "recommendation": "Use browser engine with anti_bot enabled", "credits_used": 1, "duration_ms": 1240 } ``` ```json 200 — No Protection theme={null} { "url": "https://scrapebadger.com", "antibot_systems": [], "captcha_systems": [], "is_blocked": false, "blocking_type": null, "recommendation": null, "credits_used": 1, "duration_ms": 380 } ``` ```json 200 — Cached Result theme={null} { "url": "https://protected-site.com", "antibot_systems": [ { "system": "cloudflare_turnstile", "confidence": 0.92, "details": "Turnstile widget detected in page HTML" } ], "captcha_systems": [], "is_blocked": true, "blocking_type": "cloudflare", "recommendation": "Use browser engine with anti_bot enabled", "credits_used": 0, "duration_ms": 12 } ``` # Extract Data Source: https://docs.scrapebadger.com/api-reference/endpoint/web-scraping/extract Scrape a URL and pull fields out of it with CSS/XPath selectors, AI, or both. Fetches the page the same way as [`/v1/web/scrape`](/api-reference/endpoint/web-scraping/scrape), then extracts what you asked for: * `extract_rules` run CSS or XPath selectors over the HTML and return `data`. * `ai_extract_rules` and `ai_query` ask an LLM about the page and return `ai_extraction`. Billing works like a scrape, plus the AI extraction credits when AI is requested and succeeds. Broken selectors are rejected with `422` before anything is fetched. ## Request Body The page to extract from. Field name → selector. A selector starting with `/` or `(` is treated as XPath; anything else is CSS. CSS supports `::text` and `::attr(name)`. For more control, pass an object instead of a string: * `selector` (required): the CSS or XPath selector. * `type`: `css` or `xpath`. Inferred when unset. * `all`: return every match as a list instead of the first one. * `output`: `text` (default) or `html` (the element's outer HTML). ```json theme={null} { "title": "h1", "price": "//span[@class='price']", "links": { "selector": "a::attr(href)", "all": true } } ``` Field name → plain-language description. The AI returns a JSON object with exactly these keys. ```json theme={null} { "price": "the product price with currency", "in_stock": "true if the product can be bought" } ``` A freeform question about the page. When combined with `ai_extract_rules`, the answer is added under an `answer` key. Render the page in a browser before extracting. Use this for pages that build their content with JavaScript. CSS selector to wait for before extracting (browser render). ISO 3166-1 alpha-2 country code for the proxy exit. Proxy pool: `simple`, `premium` or `ultra`. At least one of `extract_rules`, `ai_extract_rules` or `ai_query` is required. Unknown fields are rejected with `422`. ## Response `true` when the page was fetched and extraction ran. The final URL after redirects. HTTP status code of the fetched page. One key per `extract_rules` field: the first match as a string, a list with `all: true`, or `null` when nothing matched. `null` when no `extract_rules` were given. The AI's JSON answer. `null` when no AI was requested. The model that produced `ai_extraction`. Why AI extraction failed, when it did. Selector results in `data` are still returned. Engine that fetched the page. Credits charged for this request. Total time in milliseconds. ## Examples ```bash cURL theme={null} curl -X POST "https://scrapebadger.com/v1/web/extract" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://news.ycombinator.com", "extract_rules": { "top_story": ".titleline a", "links": {"selector": ".titleline a::attr(href)", "all": true} } }' ``` ```python Python theme={null} import requests response = requests.post( "https://scrapebadger.com/v1/web/extract", headers={"x-api-key": "YOUR_API_KEY"}, json={ "url": "https://example.com/product/123", "ai_extract_rules": {"price": "the product price", "name": "the product name"}, }, ) print(response.json()["ai_extraction"]) ``` ```javascript JavaScript theme={null} const res = await fetch("https://scrapebadger.com/v1/web/extract", { method: "POST", headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ url: "https://example.com", ai_query: "What is this page for, in one sentence?" }) }); console.log((await res.json()).ai_extraction); ``` ## Error Responses | Status | Description | | - | - | | `402` | Insufficient credits | | `422` | Invalid request or selector, or the target blocked the request (not billed) | | `429` | Rate limit exceeded | | `502` | The page could not be fetched, or AI-only extraction returned nothing (not billed) | ```json 200 — Selectors theme={null} { "success": true, "url": "https://news.ycombinator.com/", "status_code": 200, "data": { "first_title": "Bitwarden Dual License Model" }, "ai_extraction": null, "ai_model": null, "ai_error": null, "engine_used": "http", "credits_used": 2, "duration_ms": 1384 } ``` ```json 200 — AI query theme={null} { "success": true, "url": "https://www.example.com/", "status_code": 200, "data": null, "ai_extraction": { "answer": "This page is a documentation example domain that should not be used for testing or monitoring." }, "ai_model": "google/gemini-2.5-flash", "ai_error": null, "engine_used": "http", "credits_used": 4, "duration_ms": 1188 } ``` # Scrape URL Source: https://docs.scrapebadger.com/api-reference/endpoint/web-scraping/scrape POST /v1/web/scrape Scrape a webpage and return its content as HTML, Markdown, or plain text. ## Request Body The URL to scrape. Must be a valid HTTP or HTTPS URL. Private IPs and cloud metadata endpoints are blocked for security. HTTP method for the request: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD` or `OPTIONS`. `POST`, `PUT` and `PATCH` require `request_body`. Raw body to send with a `POST`/`PUT`/`PATCH`. Pass it as a **string**, and set `content_type` to match — there is no `form_data` parameter. ```json Submit a form theme={null} { "url": "https://example.com/login", "method": "POST", "request_body": "username=alice&password=hunter2", "content_type": "application/x-www-form-urlencoded" } ``` ```json Call a JSON API theme={null} { "url": "https://example.com/api/search", "method": "POST", "request_body": "{\"q\":\"shoes\"}", "content_type": "application/json" } ``` `Content-Type` header for `request_body`. Defaults to `application/json` when a body is present. Scraping engine tier to use. ScrapeBadger automatically selects the best approach. | Value | Engine cost | Description | | - | - | - | | `auto` | from 1 credit | Automatically picks the best engine for the target site (recommended) | | `browser` | 5 credits | Force headless browser with full JavaScript rendering | In `auto` mode, simple pages use fast HTTP (1 credit) and JavaScript-heavy pages use a browser (5 credits). **The engine cost is not the total.** Every request also pays the [`proxy_tier`](#param-proxy-tier) surcharge, so the cheapest possible scrape is **2 credits**, not 1, and a browser scrape is **6**, not 5. See [Credit costs](#credit-costs) for the full arithmetic. Proxy quality to route the request through. **This surcharge is added to every request**, on top of the engine cost. | Value | Pool | Surcharge | | - | - | - | | `simple` | Datacenter | **+1 credit** | | `premium` | Residential | **+8 credits** | | `ultra` | Premium residential / mobile | **+8 credits** | Stay on `simple` unless the target actually blocks datacenter IPs — moving to `premium` makes a browser scrape 13 credits instead of 6. Use [`max_cost`](#param-max-cost) if you want a hard ceiling. Output format for the scraped content. Applies to **text** responses only — a binary target (image, PDF, archive) ignores it and is returned untouched. * `html` — Raw HTML of the page * `markdown` — Converted to clean Markdown * `text` — Plain text with HTML tags stripped These are the only three values. There is no `raw` format — to get an unwrapped body, use [`raw_content`](#binary-files-and-raw-bodies). Force JavaScript rendering before extracting content. Automatically switches to the `browser` engine. Use this for single-page applications or pages that load content dynamically. CSS selector or XPath expression to wait for before extracting content. Only works with the `browser` engine. If `render_js` is `false` and this is set, JS rendering is forced automatically. The wait runs **after** `js_scenario`, so a login flow can fill the form, submit, and then wait for an element that only exists on the post-login page. The wait is a precondition, not a hint: if the selector has not appeared within `wait_timeout`, the request fails with `422 wait_for_timeout`, nothing is charged, and the response carries `js_scenario_report` so you can see how far the flow got. A successful response reports `wait_for_found: true`. For a best-effort dwell that never fails, use `wait_after_load` instead. ```json theme={null} { "wait_for": "#main-content" } ``` ```json theme={null} { "wait_for": "//div[@class='results']" } ``` **`render_js` alone is often not enough.** It returns the DOM once the page has loaded — which for anything drawn by a third-party widget (an embedded login form, a consent gate, a chat panel, a payment iframe) is the empty container, not the content. Those widgets fetch and paint seconds after load. If a form or list is missing from your result, name it in `wait_for` rather than raising `wait_after_load`; the selector returns as soon as the element exists instead of always paying a fixed dwell. ```json theme={null} { "url": "https://example.com/login", "render_js": true, "wait_for": "#login-container input[type=password]", "wait_timeout": 30000 } ``` Maximum time in milliseconds to wait for the `wait_for` selector to appear. Range: `1000` – `120000`. Additional milliseconds to wait after the page has finished loading, before extracting content. Useful for pages with animations or delayed rendering. Only works with browser engines. Range: `0` – `30000`. A list of browser actions to perform, in order, after the page loads and before `wait_for` is awaited and content is extracted. Forces the `browser` engine. Each step is an object with an `action` and action-specific parameters. **Supported actions:** | Action | Parameters | Description | | - | - | - | | `click` | `selector` | Click an element | | `fill` | `selector`, `value` | Click into an input and type `value` with real key events | | `scroll` | `amount` (optional, px) | Scroll down; a random 300–700 px when `amount` is omitted | | `wait` | `timeout` (ms) | Pause for a fixed duration | | `evaluate` | `script` | Run JavaScript in the page | ```json theme={null} { "js_scenario": [ { "action": "fill", "selector": "#username", "value": "me@example.com" }, { "action": "fill", "selector": "#password", "value": "hunter2" }, { "action": "click", "selector": "button[type=submit]" }, { "action": "wait", "timeout": 2000 } ] } ``` Steps run one after another and stop at the first one that fails (a selector that never becomes actionable, a script that throws). A failed step fails the request with `422 js_scenario_failed` and nothing is charged. Every response that ran a scenario includes `js_scenario_report`, one entry per executed step with its outcome and the page URL after it — the log to read when a flow does not end where you expected. An unknown action is rejected up front with a validation error rather than skipped. (`type` and `milliseconds` are accepted as aliases of `action` and `timeout`.) A unique identifier to persist cookies, fingerprint, and browser storage across multiple requests. Use the same `session_id` to maintain login state or continue a browsing session. ```json theme={null} { "session_id": "my-shopping-session" } ``` Maximum number of retry attempts when a blocking page is detected. Retries are free — you only pay for the final successful engine. Range: `0` – `10`. Whether to automatically retry when a blocking page is detected. Set to `false` to get the blocked response immediately. ISO 3166-1 alpha-2 country code for proxy geo-targeting. Routes the request through a proxy in the specified country. ```json theme={null} { "country": "US" } ``` Common values: `US`, `GB`, `DE`, `FR`, `JP`, `BR`, `AU`. Additional HTTP headers to include in the request to the target URL. Accepts a key-value object. ```json theme={null} { "custom_headers": { "Accept-Language": "en-US", "Referer": "https://google.com" } } ``` JavaScript to evaluate in the loaded page after navigation and all waits complete. Its return value replaces the page HTML in `content` (objects are JSON-serialised). May be an async arrow function. Browser engines only — forces the `browser` engine. No extra credits. Use it to pull something out of the live page that the HTML does not carry: ```json Read the page's cookies theme={null} { "url": "https://example.com", "render_js": true, "eval_js": "document.cookie" } ``` ```json Read a value the page computed theme={null} { "url": "https://example.com", "render_js": true, "eval_js": "(async () => JSON.stringify({ id: window.__APP_STATE__.id }))()" } ``` `document.cookie` returns only non-`HttpOnly` cookies — that is a browser rule, not a ScrapeBadger limit. Anti-bot vendors' session cookies are also bound to the IP and TLS fingerprint that minted them, so replaying them from a different machine does not carry the session. To keep a session alive across several scrapes, use [`session_id`](#param-session-id) instead and keep the whole flow on our side. Capture a PNG screenshot of the rendered page. Forces the browser engine. Returned in the `screenshot_url` response field as a `data:image/png;base64,…` URI. Captures the viewport unless `screenshot_full_page` is set. For a screenshot-only call, [`POST /v1/web/screenshot`](/api-reference/endpoint/web-scraping/screenshot) returns the bare base64 PNG. With `screenshot: true`, capture the whole scrollable page instead of the viewport. Browser viewport width in pixels for the render (`320` – `3840`). Browser viewport height in pixels for the render (`240` – `4320`). Record a video of the browser session (animated GIF). Forces the browser engine. Returned as base64 in the `video_url` response field. No extra charge — you pay the browser engine cost you were already paying. Useful for debugging, visual verification, or monitoring how a page loads. Attempt to bypass detected anti-bot protection using registered solvers. Adds **+5 credits** to the request cost when a solver is invoked. Only triggered when blocking is actually detected. Allow automatic escalation to more powerful engines when the initial engine is blocked. Escalation path: `http` → `browser` You only pay for the engine that succeeds — costs are **not cumulative**. Without this flag, only the selected engine is tried. Maximum credits to spend on this request. The request fails with a `400` error if the estimated cost would exceed this budget. Useful for controlling costs when using `escalate` or `anti_bot`. Minimum: `1`. Return the body directly as the HTTP response instead of wrapping it in JSON. Metadata comes back in `X-Scrape-*` response headers. Use it for two things: skipping the JSON encode/decode on large HTML payloads (saves 300–1000 ms on 1 MB+ responses), and downloading **binary** files without the \~33% base64 overhead. See [Binary files and raw bodies](#binary-files-and-raw-bodies). Cannot be combined with `ai_extract`, `screenshot` or `video` — those need the JSON envelope, so the request falls back to it automatically. Run AI-powered extraction on the scraped content using the instruction in `ai_prompt`. Adds **+10 credits** to the request cost. The scrape result is still returned even if AI extraction fails, and a failed extraction is not charged. Natural language instruction for AI data extraction. Required when `ai_extract` is `true`. Maximum 2000 characters. ```json theme={null} { "ai_extract": true, "ai_prompt": "Extract all product names and prices as a JSON array" } ``` ## Credit costs Every request is billed as **engine + proxy tier + options**. The proxy tier is charged on every request, which is why nothing costs 1 credit in practice. | Component | Credits | | - | - | | HTTP engine (`http`) | 1 | | Browser engine (`browser`) | 5 | | `proxy_tier: simple` (default) | +1 | | `proxy_tier: premium` / `ultra` | +8 | | `ai_extract` | +10 | | `anti_bot`, when a solver is actually invoked | +5 | | `screenshot`, `video`, `js_scenario`, `eval_js`, `wait_for` | +0 | Common totals: | Request | Total | | - | - | | Simple page, default tier | **2** | | JS-rendered page, default tier | **6** | | JS-rendered page, `premium` tier | **13** | | Simple page + `ai_extract` | **12** | The exact amount charged is always in the `X-Credits-Used` response header and the `credits_used` body field — trust those over any estimate. A request rejected before scraping (`400`, `422`) is charged **0**. Set [`max_cost`](#param-max-cost) to put a hard ceiling on a request. It is checked against the estimate *including* the proxy surcharge. ## Response Whether the scrape completed successfully. `false` when all retries are exhausted and the page is still blocked. The final URL after any redirects. HTTP status code from the target URL. The scraped content in the requested format. `null` when `success` is `false`, and `null` for binary targets — those come back in `content_base64`. Base64-encoded response body, returned instead of `content` when the target serves a binary payload. Only present when `is_binary` is `true`. Bodies above 25 MB are not base64-encoded — re-request those with `raw_content: true`. Whether the target returned a binary (non-text) body. The target's response `Content-Type`, normalised to the bare media type (e.g. `image/jpeg`). The output format used: `html`, `markdown`, or `text`. The engine tier that produced the final result. Total credits charged for this request: engine cost + `proxy_tier` surcharge, plus solver and AI extraction when used. See [Credit costs](#credit-costs). This is the authoritative figure and matches the `X-Credits-Used` header. Total request processing time in milliseconds. Number of retry attempts performed. `0` if the first attempt succeeded. Size of the returned content in bytes. The PNG screenshot as a `data:image/png;base64,…` URI. Only present when `screenshot: true` was requested. Base64-encoded animated GIF of the browser session. Only present when `video: true` was requested. HTTP response headers from the target URL. Whether a blocking page was detected during scraping. Details about the detected blocking page. Only present when `blocking_detected` is `true`. Whether the page is confirmed as a blocking page. Type of block detected (e.g., `cloudflare`, `datadome`, `akamai`, `kasada`). Confidence score from `0.0` to `1.0`. Human-readable description of the block. List of anti-bot systems detected on the page. System name (e.g., `cloudflare_turnstile`, `datadome`, `akamai`, `kasada`, `amazon_waf`). Confidence score from `0.0` to `1.0`. Additional detection details. List of CAPTCHA systems detected on the page. System name (e.g., `recaptcha_v2`, `recaptcha_v3`, `hcaptcha`, `geetest`). Confidence score from `0.0` to `1.0`. Additional detection details. Whether the anti-bot solver successfully bypassed the protection. Name of the solver that successfully bypassed the block. `null` if no solver was used. Whether the `wait_for` selector appeared within `wait_timeout`. `null` when no `wait_for` was requested. A miss never reaches you as a `200` — it is a `422 wait_for_timeout`. One entry per executed `js_scenario` step, in order. `null` when no scenario ran. Execution stops at the first failed step, so a report shorter than the scenario means a step broke. Zero-based index of the step in your `js_scenario`. The step's action, as you sent it. The step's selector, if it had one. Whether the step completed. Why the step failed (e.g. `TimeoutError: waiting for locator("#go")`). `null` on success. The page URL right after the step — the quickest way to see whether a submit actually navigated. Structured data extracted by the LLM based on `ai_prompt`. The shape depends on your prompt. `null` when `ai_extract` is `false` or extraction failed. The LLM model used for extraction (e.g., `gpt-4o-mini`). `null` when AI extraction was not used. Error message if AI extraction failed. The scrape result is still returned. `null` on success. ## Binary files and raw bodies `/v1/web/scrape` handles binary targets — images, PDFs, archives, fonts, audio and video — as well as HTML. The bytes are returned exactly as the origin sent them; nothing is decoded, parsed or re-encoded on the way through. This works through the same anti-bot machinery as a page scrape, so a file behind Cloudflare, DataDome or Imperva is fetched with the same engine, proxy tier and session you would use for its parent page. Pass the same `session_id` you used to scrape the page the file was linked from and the file download reuses that session's cookies and fingerprint. There are two ways to get the bytes. **`raw_content: true` — the body itself.** No base64 overhead. Best for large files and for piping straight to disk. ```bash cURL theme={null} curl -X POST "https://scrapebadger.com/v1/web/scrape" \ -H "X-API-Key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/photos/item.jpg", "raw_content": true, "session_id": "gallery-session" }' \ --output item.jpg ``` ```python Python theme={null} import requests response = requests.post( "https://scrapebadger.com/v1/web/scrape", headers={"X-API-Key": "YOUR_API_KEY"}, json={ "url": "https://example.com/photos/item.jpg", "raw_content": True, "session_id": "gallery-session", }, ) with open("item.jpg", "wb") as f: f.write(response.content) # exact bytes — do NOT use response.text print(response.headers["Content-Type"]) print(response.headers["X-Credits-Used"]) ``` ```javascript JavaScript theme={null} const response = await fetch("https://scrapebadger.com/v1/web/scrape", { method: "POST", headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ url: "https://example.com/photos/item.jpg", raw_content: true, session_id: "gallery-session", }), }); const buffer = Buffer.from(await response.arrayBuffer()); ``` Read the response as **bytes**, not text. `response.text` in Python or `response.text()` in JavaScript will decode the payload as a string and corrupt it. Use `response.content` / `response.arrayBuffer()`. **JSON with `content_base64` — one request, metadata included.** Use this when you also want `credits_used`, `engine_used` or the protection detections alongside the file. ```python Python theme={null} import base64 import requests data = requests.post( "https://scrapebadger.com/v1/web/scrape", headers={"X-API-Key": "YOUR_API_KEY"}, json={"url": "https://example.com/report.pdf"}, ).json() if data["is_binary"]: with open("report.pdf", "wb") as f: f.write(base64.b64decode(data["content_base64"])) print(data["content_type"]) # application/pdf else: print(data["content"]) # a text target — HTML/markdown/text ``` Binary responses served with `raw_content` always carry `Content-Disposition: attachment` and `X-Content-Type-Options: nosniff`, and their `Content-Type` is restricted to a known-safe set — scraped bytes are never labelled in a way that would let a browser execute them. Bodies larger than 25 MB are not base64-encoded into JSON. Those return `content_base64: null` with a `detail` telling you to re-request using `raw_content: true`, which returns them without the base64 expansion. Very large files are still held in memory end to end, so treat a few hundred MB as the practical ceiling for a single request. ## Examples ### Basic scrape ```bash cURL theme={null} curl -X POST "https://scrapebadger.com/v1/web/scrape" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://scrapebadger.com", "format": "markdown"}' ``` ```python Python theme={null} import requests response = requests.post( "https://scrapebadger.com/v1/web/scrape", headers={"x-api-key": "YOUR_API_KEY"}, json={"url": "https://scrapebadger.com", "format": "markdown"} ) print(response.json()["content"]) ``` ```javascript JavaScript theme={null} const res = await fetch("https://scrapebadger.com/v1/web/scrape", { method: "POST", headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ url: "https://scrapebadger.com", format: "markdown" }) }); const data = await res.json(); console.log(data.content); ``` ### JavaScript rendering with wait ```json theme={null} { "url": "https://scrapebadger.com/spa-page", "format": "html", "render_js": true, "wait_for": "#dynamic-content", "wait_timeout": 10000 } ``` ### AI extraction ```json theme={null} { "url": "https://scrapebadger.com/products", "format": "markdown", "ai_extract": true, "ai_prompt": "Extract all product names, prices, and ratings as a JSON array of objects with keys: name, price, rating" } ``` ### Full anti-bot bypass with budget ```json theme={null} { "url": "https://heavily-protected-site.com", "format": "markdown", "escalate": true, "anti_bot": true, "max_cost": 20, "country": "US" } ``` ### Browser automation scenario Log in, then wait for an element that only exists once the login succeeded. If the flow never gets there you receive a free `422` with the step-by-step report instead of a billed copy of the login page. ```json theme={null} { "url": "https://example.com/login", "js_scenario": [ { "action": "fill", "selector": "#username", "value": "me@example.com" }, { "action": "fill", "selector": "#password", "value": "hunter2" }, { "action": "click", "selector": "button[type=submit]" } ], "wait_for": "#account-dashboard", "wait_timeout": 60000 } ``` Infinite scroll: ```json theme={null} { "url": "https://scrapebadger.com/infinite-scroll", "format": "text", "js_scenario": [ { "action": "scroll", "amount": 1000 }, { "action": "wait", "timeout": 2000 }, { "action": "scroll", "amount": 1000 }, { "action": "wait", "timeout": 2000 } ] } ``` ## Error Responses | Status | Description | | - | - | | `400` | Invalid URL, cost exceeds `max_cost`, or requested engine not available | | `402` | Insufficient credits | | `422` | Blocking detected after all retries exhausted (`success: false`, `blocking_details` populated); the `wait_for` selector never appeared (`error: "wait_for_timeout"`); a `js_scenario` step failed (`error: "js_scenario_failed"`); or the body contained an unknown field (`error: "unknown_request_field"`). Never charged. | | `429` | Rate limit exceeded | | `500` | Unexpected server error | ### Unknown request fields A field this endpoint does not define is rejected rather than ignored, so a request never looks like it succeeded at something it did not do. The response names the offending field and lists everything the endpoint accepts, and nothing is charged. ```json 422 — Unknown request field theme={null} { "error": "unknown_request_field", "detail": "Unknown request field(s): return_cookies. These were silently ignored by older versions; they are now rejected so a request never appears to succeed at something it did not do.", "unknown_fields": ["return_cookies"], "accepted_fields": ["ai_extract", "ai_prompt", "anti_bot", "..."] } ``` There is no `return_cookies` or `form_data` parameter. To read cookies use [`eval_js`](#param-eval-js); to send a request body use [`method`](#param-method) with `request_body`. ```json 200 — Success theme={null} { "success": true, "url": "https://scrapebadger.com", "status_code": 200, "content": "# Example Domain\n\nThis domain is for use in illustrative examples...", "format": "markdown", "engine_used": "http", "credits_used": 2, "duration_ms": 342, "retries_used": 0, "content_length": 1256, "screenshot_url": null, "video_url": null, "headers": { "content-type": "text/html; charset=UTF-8" }, "blocking_detected": false, "blocking_details": null, "antibot_systems": [], "captcha_systems": [], "anti_bot_solved": false, "solver_used": null, "ai_extraction": null, "ai_model": null, "ai_error": null } ``` ```json 200 — With AI Extraction theme={null} { "success": true, "url": "https://scrapebadger.com/products", "status_code": 200, "content": "# Products\n\n...", "format": "markdown", "engine_used": "http", "credits_used": 12, "duration_ms": 2150, "retries_used": 0, "content_length": 8432, "screenshot_url": null, "video_url": null, "headers": {}, "blocking_detected": false, "blocking_details": null, "antibot_systems": [], "captcha_systems": [], "anti_bot_solved": false, "solver_used": null, "ai_extraction": [ { "name": "Widget Pro", "price": "$29.99", "rating": 4.5 }, { "name": "Widget Basic", "price": "$9.99", "rating": 4.2 } ], "ai_model": "gpt-4o-mini", "ai_error": null } ``` ```json 422 — Blocked theme={null} { "success": false, "url": "https://protected-site.com", "status_code": 403, "content": null, "format": "markdown", "engine_used": "http", "credits_used": 0, "duration_ms": 5230, "retries_used": 3, "content_length": 0, "screenshot_url": null, "video_url": null, "headers": {}, "blocking_detected": true, "blocking_details": { "is_blocked": true, "block_type": "cloudflare", "confidence": 0.95, "details": "Cloudflare challenge page detected" }, "antibot_systems": [ { "system": "cloudflare_turnstile", "confidence": 0.95, "details": null } ], "captcha_systems": [], "anti_bot_solved": false, "solver_used": null, "ai_extraction": null, "ai_model": null, "ai_error": null } ``` # Screenshot Source: https://docs.scrapebadger.com/api-reference/endpoint/web-scraping/screenshot Render a URL in a real browser and get a PNG screenshot back. Loads the page in the browser engine and returns a PNG of the viewport, or of the whole scrollable page with `full_page`. It is billed like a browser scrape plus the proxy tier, the same as `POST /v1/web/scrape` with `screenshot: true`. If the page loads but no screenshot comes back, the call returns `502` and costs **0 credits**. ## Request Body The page to capture. Must be a valid HTTP or HTTPS URL. Capture the whole scrollable page instead of only the viewport. Viewport width in pixels. Range: `320` – `3840`. Viewport height in pixels. Range: `240` – `4320`. CSS selector to wait for before capturing, e.g. `"#main"`. ISO 3166-1 alpha-2 country code for the proxy exit, e.g. `"US"`. Proxy pool: `simple`, `premium` or `ultra`. Same pricing as on [`/v1/web/scrape`](/api-reference/endpoint/web-scraping/scrape). Unknown fields are rejected with `422`. ## Response `true` when a screenshot was captured. The final URL after redirects. HTTP status code of the captured page. Always `image/png`. The PNG image, base64-encoded (no `data:` prefix). Browser engine that rendered the page. Credits charged for this request. Total time in milliseconds. ## Examples ```bash cURL theme={null} curl -X POST "https://scrapebadger.com/v1/web/screenshot" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com", "full_page": true, "width": 1280}' \ | jq -r .screenshot | base64 --decode > page.png ``` ```python Python theme={null} import base64 import requests response = requests.post( "https://scrapebadger.com/v1/web/screenshot", headers={"x-api-key": "YOUR_API_KEY"}, json={"url": "https://example.com", "full_page": True, "width": 1280}, ) response.raise_for_status() with open("page.png", "wb") as f: f.write(base64.b64decode(response.json()["screenshot"])) ``` ```javascript JavaScript theme={null} import { writeFile } from "node:fs/promises"; const res = await fetch("https://scrapebadger.com/v1/web/screenshot", { method: "POST", headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ url: "https://example.com", full_page: true, width: 1280 }) }); const { screenshot } = await res.json(); await writeFile("page.png", Buffer.from(screenshot, "base64")); ``` ## Error Responses | Status | Description | | - | - | | `402` | Insufficient credits | | `422` | Invalid request, or the target blocked the request (not billed) | | `429` | Rate limit exceeded, or the browser farm is at capacity (not billed) | | `502` | The page loaded but no screenshot was captured (not billed) | ```json 200 theme={null} { "success": true, "url": "https://www.example.com/", "status_code": 200, "content_type": "image/png", "screenshot": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAO/CAIAAA...", "engine_used": "cloakbrowser", "credits_used": 6, "duration_ms": 4210 } ``` # Autocomplete Source: https://docs.scrapebadger.com/api-reference/endpoint/yahoo/autocomplete GET https://scrapebadger.com/v1/yahoo/autocomplete Get Yahoo search-box query suggestions for a partial term. Get Yahoo's search-box suggestions for a partial term. The cheapest call in this API — useful for expanding a seed keyword into real Yahoo queries before running [`/search`](/api-reference/endpoint/yahoo/search) on each one. **Credits:** 1 ## Authorization Your ScrapeBadger API key. ## Query Parameters Partial search term, e.g. `coff`. Yahoo market code (lowercase), e.g. `us`. Suggestions are market-specific. See [`/markets`](/api-reference/endpoint/yahoo/list-markets). ## Response Echo of the requested term. The market the suggestions were fetched for. Number of suggestions. Suggested queries, in Yahoo's order. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/yahoo/autocomplete?query=coff" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/yahoo/autocomplete?" + new URLSearchParams({ query: "coff" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { suggestions } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/yahoo/autocomplete", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "coff"}, ) suggestions = res.json()["suggestions"] ``` ```json Response theme={null} { "query": "coff", "market": "us", "result_count": 8, "suggestions": [ "coffee", "coffee maker", "coffee near me", "coffee shop", "coffee table", "coffee grinder", "coffee machine", "coffee beans" ] } ``` # Image Search Source: https://docs.scrapebadger.com/api-reference/endpoint/yahoo/images GET https://scrapebadger.com/v1/yahoo/images Search Yahoo Images — full-size URL, thumbnail, source page and pixel dimensions per result. Search Yahoo Images. Each result carries the **full-size image URL**, a thumbnail, the page the image lives on, and its pixel dimensions. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `golden retriever`. Yahoo market code (lowercase), e.g. `us`. See [`/markets`](/api-reference/endpoint/yahoo/list-markets). Echoed back — the image vertical is US-hosted, see [Page size](#page-size). Results to return, `1`–`100`. Trims the rendered grid — see [Page size](#page-size). ## Response Echo of the requested query. The market the results were fetched for. Images returned. Image results. 1-based rank. Full-size image URL. Thumbnail URL. The page the image lives on. Full-size width in pixels. Full-size height in pixels. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/yahoo/images?query=golden+retriever&count=10" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/yahoo/images?" + new URLSearchParams({ query: "golden retriever", count: "10" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/yahoo/images", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "golden retriever", "count": 10}, ) data = res.json() ``` ```json Response theme={null} { "query": "golden retriever", "market": "us", "result_count": 10, "results": [ { "position": 1, "title": "Golden Retriever Dog Breed Information", "image_url": "https://www.akc.org/wp-content/uploads/2017/11/Golden-Retriever.jpg", "thumbnail_url": "https://tse1.mm.bing.net/th?id=OIP.abc123", "source_url": "https://www.akc.org/dog-breeds/golden-retriever/", "source_domain": "akc.org", "width": 1920, "height": 1080 } ] } ``` ## Page size Yahoo renders roughly **60 tiles** into the first response and has no native page-size parameter, so `count` trims that list rather than paginating. Asking for more than Yahoo rendered simply returns everything available. The image vertical only exists on `images.search.yahoo.com`, so results are fetched from that fixed US host regardless of the `market` you pass; the value is echoed back for consistency. # List Markets Source: https://docs.scrapebadger.com/api-reference/endpoint/yahoo/list-markets GET https://scrapebadger.com/v1/yahoo/markets List the 35 supported Yahoo market codes and the regional search host each maps to. Free. List the supported Yahoo market codes. This endpoint is **free**. **Credits:** 0 Yahoo localizes search through **regional subdomains** — `fr.search.yahoo.com`, `de.search.yahoo.com`, and so on — rather than a query parameter. The lowercase `market` code selects the subdomain, returned here as `host`. **Yahoo Japan is not covered.** `search.yahoo.co.jp` is operated by a separate company running its own engine and page structure — it is not a Yahoo Search market and is deliberately excluded. ## Authorization Your ScrapeBadger API key. ## Response Number of markets. Supported markets. Yahoo market code (lowercase), e.g. `us`. e.g. `United States`. Two-letter country code, e.g. `US`. Regional search host, e.g. `fr.search.yahoo.com`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/yahoo/markets" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch("https://scrapebadger.com/v1/yahoo/markets", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY }, }); const { markets } = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/yahoo/markets", headers={"X-API-Key": "YOUR_API_KEY"}, ) markets = res.json()["markets"] ``` ```json Response theme={null} { "result_count": 35, "markets": [ { "code": "us", "name": "United States", "country": "US", "host": "search.yahoo.com" }, { "code": "uk", "name": "United Kingdom", "country": "GB", "host": "uk.search.yahoo.com" }, { "code": "de", "name": "Germany", "country": "DE", "host": "de.search.yahoo.com" }, { "code": "fr", "name": "France", "country": "FR", "host": "fr.search.yahoo.com" }, { "code": "br", "name": "Brazil", "country": "BR", "host": "br.search.yahoo.com" } ] } ``` ## Supported markets | Region | Codes | | - | - | | English-speaking | `us`, `uk`, `ca`, `au`, `in`, `ie`, `nz`, `za` | | Europe | `fr`, `de`, `es`, `it`, `nl`, `be`, `ch`, `at`, `se`, `no`, `dk`, `fi`, `gr`, `tr` | | Latin America | `br`, `mx`, `ar`, `cl`, `co` | | Asia-Pacific | `sg`, `my`, `ph`, `th`, `tw`, `hk`, `id`, `vn` | # News Search Source: https://docs.scrapebadger.com/api-reference/endpoint/yahoo/news GET https://scrapebadger.com/v1/yahoo/news Search Yahoo News — headline, publisher, syndication source, snippet and thumbnail per article. Search Yahoo News. Every article carries the resolved destination URL, the publisher, the syndication source it ran through (`via`), a snippet and a thumbnail — plus Yahoo's reported total match count for the query. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `interest rates`. Yahoo market code (lowercase), e.g. `us`. See [`/markets`](/api-reference/endpoint/yahoo/list-markets). ## Response Echo of the requested query. The market the results were fetched for. Yahoo's reported total match count (approximate), e.g. `1420000`. The count as displayed, e.g. `About 1,420,000 results`. Articles returned. News articles. 1-based rank. Destination article URL — Yahoo's redirect is resolved. Publisher name. Syndication source, e.g. `via Yahoo Finance`. **Relative** age as displayed, e.g. `26 minutes ago` — see [Timestamps](#timestamps). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/yahoo/news?query=interest+rates" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/yahoo/news?" + new URLSearchParams({ query: "interest rates" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/yahoo/news", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "interest rates"}, ) data = res.json() ``` ```json Response theme={null} { "query": "interest rates", "market": "us", "total_results": 1420000, "total_results_text": "About 1,420,000 results", "result_count": 10, "results": [ { "position": 1, "title": "Fed Holds Rates Steady as Inflation Cools", "url": "https://www.reuters.com/markets/us/fed-holds-rates-steady", "source": "Reuters", "via": "via Yahoo Finance", "snippet": "The Federal Reserve kept its benchmark interest rate unchanged...", "published": "26 minutes ago", "thumbnail_url": "https://s.yimg.com/uu/api/res/1.2/abc123--/news-thumb.jpg" } ] } ``` ## Timestamps Yahoo News renders **relative ages only** — `26 minutes ago`, `3 hours ago`, `2 days ago` — and shows no absolute date anywhere on the page. `published` is that display string verbatim; there is no `published_at` or `published_utc` field, unlike the [Bing news endpoint](/api-reference/endpoint/bing/news), which reads an RSS feed. Derive absolute times from your own request time if you need them. # Web Search Source: https://docs.scrapebadger.com/api-reference/endpoint/yahoo/search GET https://scrapebadger.com/v1/yahoo/search Search the Yahoo web SERP — organic results, ads and related searches. Search Yahoo's web SERP. Organic results carry the **resolved destination URL** (Yahoo's tracking redirect is decoded), display URL and snippet. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `coffee machine`. Yahoo market code (lowercase), e.g. `us`, `uk`, `de`. See [`/markets`](/api-reference/endpoint/yahoo/list-markets). Zero-based **absolute** result offset. Yahoo serves 7 organic results per page, so page 2 is `offset=7` — see [Pagination](#pagination). One of `off`, `moderate`, `strict`. ## Response Echo of the requested query. The market the results were fetched for. Organic results returned in this response. Organic results. 1-based rank within this page. Destination URL — Yahoo's redirect is resolved. Human-readable URL shown by Yahoo. Ads served for this query, when present. Yahoo's related query suggestions. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/yahoo/search?query=coffee+machine&market=uk" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/yahoo/search?" + new URLSearchParams({ query: "coffee machine", market: "uk" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/yahoo/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "coffee machine", "market": "uk"}, ) data = res.json() ``` ```json Response theme={null} { "query": "coffee machine", "market": "uk", "result_count": 7, "results": [ { "position": 1, "title": "The 9 Best Coffee Makers of 2026, Tested & Reviewed", "url": "https://www.seriouseats.com/best-coffee-makers-5069325", "display_url": "www.seriouseats.com/best-coffee-makers", "snippet": "We brewed hundreds of cups to find the best drip coffee makers..." } ], "ads": [ { "position": 1, "title": "Coffee Machines - Free Delivery", "url": "https://www.example-retailer.com/coffee", "display_url": "www.example-retailer.com", "snippet": "Shop our range of bean-to-cup machines." } ], "related_searches": ["best coffee machine 2026", "espresso machine", "bean to cup coffee machine"] } ``` ## Pagination Yahoo serves **7 organic results per page** and exposes no page-size parameter. `offset` is a zero-based absolute result offset — page 2 is `offset=7`, page 3 is `offset=14`. Yahoo also reports no total match count on the web SERP, so there is no `total_results` field here. Yahoo web search is **Bing-syndicated** — organic results come from Microsoft's index. Expect results close to, but not identical to, the [Bing API](/bing/overview): Yahoo applies its own ranking, ad load and layout on top. # Video Search Source: https://docs.scrapebadger.com/api-reference/endpoint/yahoo/videos GET https://scrapebadger.com/v1/yahoo/videos Search Yahoo Videos — title, thumbnail, duration, source platform, description and views per result. Search Yahoo Videos. Each result carries the destination watch URL, thumbnail, duration, the host platform (e.g. YouTube), a description, and views as displayed. **Credits:** 5 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `espresso tutorial`. Yahoo market code (lowercase), e.g. `us`. See [`/markets`](/api-reference/endpoint/yahoo/list-markets). Echoed back — the video vertical is US-hosted, see [Page size](#page-size). Results to return, `1`–`100`. Trims the rendered grid — see [Page size](#page-size). ## Response Echo of the requested query. The market the results were fetched for. Videos returned. Video results. 1-based rank. Destination watch URL. e.g. `13:47`. Host platform, e.g. `YouTube`. View count as displayed, e.g. `1.8M views`. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/yahoo/videos?query=espresso+tutorial&count=10" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/yahoo/videos?" + new URLSearchParams({ query: "espresso tutorial", count: "10" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/yahoo/videos", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "espresso tutorial", "count": 10}, ) data = res.json() ``` ```json Response theme={null} { "query": "espresso tutorial", "market": "us", "result_count": 10, "results": [ { "position": 1, "title": "How to Make Espresso — Beginner's Guide", "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "thumbnail_url": "https://tse2.mm.bing.net/th?id=OVP.abc123", "duration": "13:47", "source": "YouTube", "source_domain": "youtube.com", "description": "Everything you need to pull a good shot at home, start to finish.", "views": "1.8M views" } ] } ``` `duration` and `views` are returned **as Yahoo displays them** (`13:47`, `1.8M views`) — they are display strings, not numbers. ## Page size Yahoo renders roughly **60 tiles** into the first response and has no native page-size parameter, so `count` trims that list rather than paginating. The video vertical only exists on `video.search.yahoo.com`, so results are fetched from that fixed US host regardless of the `market` you pass; the value is echoed back for consistency. # Reverse Image Search Source: https://docs.scrapebadger.com/api-reference/endpoint/yandex/images-reverse GET https://scrapebadger.com/v1/yandex/images/reverse Reverse image search by URL — find the pages that host an image, visually similar images, detected tags and other sizes, via Yandex's CBIR flow. Reverse image search by URL. Pass a public image URL and Yandex returns the web pages that host (a copy of) it, visually similar images, detected object tags and the same image at other resolutions. **Credits:** 7 ## Authorization Your ScrapeBadger API key. ## Query Parameters Public URL of the image to reverse-search. Yandex domain: `tr` (default), `com`, `ru`, `by`, `kz`, `uz`. `com`/`ru` have a lower success rate. See [`/markets`](/api-reference/endpoint/yandex/list-markets). ## Response Echo of the image URL you searched. The domain the search ran on. The Yandex CBIR URL that was scraped. Yandex's internal id for the uploaded image query. `true` when Yandex found no matches for the image. Yandex's preview of the query image: `url`, `width`, `height`. Number of hosting pages returned. Web pages that host (a copy of) the image. The hosting page. `url`, `width`, `height`. The image on that page: `url`, `width`, `height`. Visually similar images (`title`, `thumbnail`, `url`, `width`, `height`). Objects/refinements Yandex detected in the image (`text`, `url`). The same image at different resolutions (`label`, `url`, `width`, `height`). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/yandex/images/reverse?image_url=https://example.com/photo.jpg&domain=tr" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/yandex/images/reverse?" + new URLSearchParams({ image_url: "https://example.com/photo.jpg", domain: "tr" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/yandex/images/reverse", headers={"X-API-Key": "YOUR_API_KEY"}, params={"image_url": "https://example.com/photo.jpg", "domain": "tr"}, ) data = res.json() ``` ```json Response theme={null} { "query_image_url": "https://example.com/photo.jpg", "domain": "tr", "search_url": "https://yandex.com.tr/images/search?cbir_id=...&rpt=imageview", "cbir_id": "1234567/abcdef", "is_empty": false, "preview": { "url": "https://avatars.mds.yandex.net/i?id=preview", "width": 450, "height": 300 }, "result_count": 12, "sites": [ { "title": "Product page", "description": "Espresso machine — 2L, stainless steel", "url": "https://shop.example.com/espresso", "domain": "shop.example.com", "thumbnail": { "url": "https://avatars.mds.yandex.net/i?id=thumb", "width": 200, "height": 133 }, "original_image": { "url": "https://shop.example.com/img/espresso.jpg", "width": 2000, "height": 1333 } } ], "similar_images": [ { "title": "Similar machine", "thumbnail": "https://avatars.mds.yandex.net/i?id=sim", "url": "https://other.example.com/machine", "width": 1200, "height": 800 } ], "tags": [{ "text": "espresso machine", "url": "https://yandex.com.tr/images/search?text=espresso+machine" }], "other_sizes": [{ "label": "Original 2000×1333", "url": "https://shop.example.com/img/espresso.jpg", "width": 2000, "height": 1333 }] } ``` ## Notes Reverse search runs Yandex's two-step CBIR flow: the API derives a `cbir_id` for your image, then reads the hosting pages, similar images, tags and other sizes. When Yandex finds nothing, `is_empty` is `true` and the result arrays are empty. # Image Search Source: https://docs.scrapebadger.com/api-reference/endpoint/yandex/images-search GET https://scrapebadger.com/v1/yandex/images/search Search Yandex Images by text query — full-resolution image URL, dimensions, thumbnail and source page. Search Yandex Images by text. Each result carries the full-resolution image (`url`, `width`, `height`), a thumbnail and the page the image lives on. **Credits:** 7 ## Authorization Your ScrapeBadger API key. ## Query Parameters Image search keywords, e.g. `coffee machine`. Yandex domain: `tr` (default), `com`, `ru`, `by`, `kz`, `uz`. `com`/`ru` have a lower success rate. See [`/markets`](/api-reference/endpoint/yandex/list-markets). Result page, `1`–`25`. ## Response Echo of the requested query. The domain the results were fetched from. The page returned. The Yandex URL that was scraped. Image results returned in this response. Image results. 1-based rank. The site the image is from. The page hosting the image. Yandex thumbnail URL. Full-resolution image: `url`, `width`, `height`. Related image-search suggestions. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/yandex/images/search?query=coffee+machine&domain=tr" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/yandex/images/search?" + new URLSearchParams({ query: "coffee machine", domain: "tr" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/yandex/images/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "coffee machine", "domain": "tr"}, ) data = res.json() ``` ```json Response theme={null} { "query": "coffee machine", "domain": "tr", "page": 1, "search_url": "https://yandex.com.tr/images/search?text=coffee+machine", "result_count": 30, "results": [ { "position": 1, "title": "Espresso Machine", "source": "example.com", "source_url": "https://www.example.com/product/espresso", "thumbnail": "https://avatars.mds.yandex.net/i?id=abc123", "image": { "url": "https://www.example.com/img/espresso.jpg", "width": 2000, "height": 1333 }, "snippet": "Stainless steel espresso machine" } ], "suggested_searches": ["espresso machine", "bean to cup"] } ``` # List Markets Source: https://docs.scrapebadger.com/api-reference/endpoint/yandex/list-markets GET https://scrapebadger.com/v1/yandex/markets List the Yandex domains this API supports, with each domain's default region and language. List the supported Yandex domains. Yandex localises by **domain (TLD)**, not a query parameter — each market bundles a domain with its default region (`lr`) and language. **Credits:** 0 (free) ## Authorization Your ScrapeBadger API key. ## Response Number of markets returned. Supported markets. Short market code, e.g. `tr`, `com`, `ru`. The Yandex host, e.g. `yandex.com.tr`. Two-letter country code. Default Yandex region id for the domain. Default UI language. Human-readable name. Whether this domain reliably clears anti-bot (`tr` is the safe default). ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/yandex/markets" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch("https://scrapebadger.com/v1/yandex/markets", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY }, }); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/yandex/markets", headers={"X-API-Key": "YOUR_API_KEY"}, ) data = res.json() ``` ```json Response theme={null} { "result_count": 6, "markets": [ { "code": "tr", "domain": "yandex.com.tr", "country_code": "TR", "default_lr": 11508, "lang": "tr", "name": "Turkey", "clears_reliably": true }, { "code": "com", "domain": "yandex.com", "country_code": "US", "default_lr": 84, "lang": "en", "name": "International (English)", "clears_reliably": false }, { "code": "ru", "domain": "yandex.ru", "country_code": "RU", "default_lr": 225, "lang": "ru", "name": "Russia", "clears_reliably": false }, { "code": "by", "domain": "yandex.by", "country_code": "BY", "default_lr": 149, "lang": "ru", "name": "Belarus", "clears_reliably": false }, { "code": "kz", "domain": "yandex.kz", "country_code": "KZ", "default_lr": 159, "lang": "ru", "name": "Kazakhstan", "clears_reliably": false }, { "code": "uz", "domain": "yandex.uz", "country_code": "UZ", "default_lr": 171, "lang": "ru", "name": "Uzbekistan", "clears_reliably": false } ] } ``` Default to `tr` (`yandex.com.tr`) — it's the only domain that reliably clears Yandex's anti-bot. Switch domains only when you need another country's index. # Web Search Source: https://docs.scrapebadger.com/api-reference/endpoint/yandex/search GET https://scrapebadger.com/v1/yandex/search Search the Yandex web SERP — organic results, ads, inline images and videos, related searches and pagination. Search Yandex's web SERP. Organic results carry the **resolved destination URL** (Yandex's `/r?u=` tracking redirects are decoded), displayed URL, domain, snippet, favicon and sitelinks. **Credits:** 7 ## Authorization Your ScrapeBadger API key. ## Query Parameters Search keywords, e.g. `coffee machine`. Yandex domain: `tr` (yandex.com.tr, the default — reliably clears anti-bot), `com`, `ru`, `by`, `kz`, `uz`. `com`/`ru` have a lower success rate. See [`/markets`](/api-reference/endpoint/yandex/list-markets). Result page, `1`–`25`. Yandex region id, e.g. `213` = Moscow, `84` = USA. Defaults to the domain's region. UI language: `ru`, `en`, `tr`, `be`, `kk`, `uk`. ## Response Echo of the requested query. The domain the results were fetched from. The Yandex region id used. The UI language used. The page returned. The Yandex URL that was scraped. Yandex's reported total match count (approximate). Yandex's "did you mean" suggestion, when present. Organic results returned in this response. Organic results. 1-based rank within this page. Destination URL — the `/r?u=` redirect is resolved. Human-readable URL shown by Yandex. `title`, `url`, `snippet` — links under the main result. Ads served for this query, when present (`position`, `title`, `url`, `displayed_url`, `domain`, `snippet`, `sitelinks`). Image results shown inline on the SERP (`title`, `source_url`, `thumbnail`). Video results shown inline (`title`, `url`, `source`, `channel`, `duration`, `views`, `date`, `thumbnail`). Knowledge-panel data, when Yandex renders one. Yandex's related query suggestions. `current`, `next_url`, `other_pages` map of page → URL. ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/yandex/search?query=coffee+machine&domain=tr" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/yandex/search?" + new URLSearchParams({ query: "coffee machine", domain: "tr" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/yandex/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "coffee machine", "domain": "tr"}, ) data = res.json() ``` ```json Response theme={null} { "query": "coffee machine", "domain": "tr", "region_lr": 11508, "lang": "tr", "page": 1, "search_url": "https://yandex.com.tr/search/?text=coffee+machine", "total_results": 14000000, "spellcheck": null, "result_count": 10, "organic_results": [ { "position": 1, "title": "Coffee Machines — Buyer's Guide", "url": "https://www.example.com/coffee-machines", "displayed_url": "example.com › coffee-machines", "domain": "example.com", "snippet": "Compare drip, espresso and bean-to-cup machines...", "favicon": "https://favicon.yandex.net/favicon/example.com", "sitelinks": [] } ], "ads": [], "inline_images": [], "inline_videos": [], "knowledge_graph": null, "related_searches": ["best coffee machine", "espresso machine"], "pagination": { "current": 1, "next_url": "https://yandex.com.tr/search/?text=coffee+machine&p=1", "other_pages": {} } } ``` ## Anti-bot Keep `domain=tr`. `yandex.com` and `yandex.ru` serve SmartCaptcha far more often and return `422` (not billed). The scraper retries on a fresh exit, but the `tr` domain clears most reliably. # Get Channel Source: https://docs.scrapebadger.com/api-reference/endpoint/youtube/channel GET /v1/youtube/channels/{channel_id} Full detail for a YouTube channel — header, About tab, stats, branding, and links. ## Path Parameters The channel identifier. Accepts a canonical channel id (`UC…`), an `@handle`, or a custom URL slug. Handles and custom URLs are resolved automatically. Examples: `UCBR8-60-B28hp2BmDPdntcQ`, `@YouTube`, `youtube` ## Query Parameters Content region (ISO 3166-1 alpha-2). Examples: `US`, `GB`, `DE`, `JP`. UI / interface language (BCP-47). Examples: `en`, `de`, `fr`, `ja`. ## Response Canonical channel id (`UC…`). Channel title (nullable). Channel display name (nullable). Channel `@handle` (nullable). Custom URL slug (nullable). Full channel URL (nullable). Channel description (nullable). Links parsed from the description, with `title` and `url`. Subscriber count (nullable). Subscriber count as displayed (nullable). Whether the subscriber count is hidden (nullable). Total uploaded videos (nullable). Total videos as displayed (nullable). Total channel views (nullable). Total views as displayed (nullable). ISO 8601 channel creation date (nullable). Unix channel creation timestamp (nullable). Channel country code (nullable). Channel location text (nullable). Channel keywords. Channel tags. Whether the channel is verified (nullable). Whether the channel is age-restricted (nullable). Whether the channel is family-safe (nullable). Whether the channel is monetized (nullable). Whether the channel is auto-generated (nullable). Whether the channel is made for kids (nullable). Avatar image URL (nullable). Banner image URL (nullable). TV banner image URL (nullable). Mobile banner image URL (nullable). Avatar variants with `url`, `width`, `height`. Banner variants with `url`, `width`, `height`. External links from the channel header, with `title` and `url`. Available channel tabs, e.g. `Videos`, `Shorts`, `Playlists`. Country codes where the channel is available. Featured / related channel objects. A preview of the channel's latest videos. ISO 8601 timestamp when the channel was scraped. Unix timestamp when the channel was scraped. ### Example Response ```json theme={null} { "channel_id": "UCBR8-60-B28hp2BmDPdntcQ", "title": "YouTube", "channel_name": "YouTube", "channel_username": "@YouTube", "custom_url": "@YouTube", "channel_url": "https://www.youtube.com/@YouTube", "description": "YouTube's Official Channel helps you discover what's new & trending globally.", "number_of_subscribers": 42000000, "subscriber_count_text": "42M subscribers", "channel_total_videos": 1200, "channel_total_views": 9800000000, "joined_at": "2005-09-19T00:00:00Z", "country": "US", "is_verified": true, "is_family_safe": true, "avatar": "https://yt3.googleusercontent.com/abc/avatar.jpg", "banner": "https://yt3.googleusercontent.com/abc/banner.jpg", "tabs": ["Home", "Videos", "Shorts", "Playlists", "Community"], "scraped_at": "2026-06-21T12:00:00Z" } ``` ## Lightweight Lookups | Endpoint | Description | Cost | | - | - | - | | `GET /v1/youtube/channels/{channel_id}/about` | About-tab payload only — description, links, stats, joined date, country (`ChannelAbout`). | 2 credits | | `GET /v1/youtube/channels/{channel_id}/subscriber_count` | Fast subscriber-count-only response (`SubscriberCount`). | 2 credits | A full channel-detail request costs **5 credits**; the `/about` and `/subscriber_count` lookups cost **2 credits** each. Failed requests are not charged. # Channel Videos Source: https://docs.scrapebadger.com/api-reference/endpoint/youtube/channel-videos GET /v1/youtube/channels/{channel_id}/videos List a YouTube channel's uploaded videos, paginated by continuation token. ## Path Parameters The channel id (`UC…`), an `@handle`, or a custom URL slug. Examples: `UCBR8-60-B28hp2BmDPdntcQ`, `@YouTube` ## Query Parameters Sort order for the channel's videos. | Value | Description | | - | - | | `newest` | Most recent first (default) | | `oldest` | Oldest first | | `popular` | Most popular first | Continuation token from a previous response to fetch the next page. ## Response The channel id the items belong to. Array of the channel's videos (polymorphic `SearchResult` shape). Result type, e.g. `video` or `short`. Video id (nullable). Video title (nullable). Full watch URL (nullable). Best thumbnail URL (nullable). Human-readable duration (nullable). Duration in seconds (nullable). View count (nullable). View count as displayed (nullable). Relative publish time (nullable). Result badges, e.g. `4K`, `CC`. Whether the video is live (nullable). Whether the item is a Short (nullable). Token to fetch the next page (nullable when no more pages). ### Example Response ```json theme={null} { "channel_id": "UCBR8-60-B28hp2BmDPdntcQ", "items": [ { "type": "video", "video_id": "abc123XYZ_0", "title": "What's new on YouTube", "url": "https://www.youtube.com/watch?v=abc123XYZ_0", "thumbnail": "https://i.ytimg.com/vi/abc123XYZ_0/hqdefault.jpg", "duration": "2:14", "length_seconds": 134, "view_count": 1820000, "view_count_text": "1.8M views", "published_time_text": "3 weeks ago", "is_short": false } ], "continuation": "4qmFsgKZARIY..." } ``` ## Other Channel Tabs The same paginated shape powers every channel sub-surface — swap the path segment: | Endpoint | Returns | | - | - | | `GET /v1/youtube/channels/{channel_id}/shorts` | The channel's Shorts | | `GET /v1/youtube/channels/{channel_id}/streams` | The channel's live streams | | `GET /v1/youtube/channels/{channel_id}/playlists` | The channel's playlists | | `GET /v1/youtube/channels/{channel_id}/community` | The channel's community posts (`posts` array of `CommunityPost`) | | `GET /v1/youtube/channels/{channel_id}/search?query=...` | Search within the channel (returns a `SearchResponse`) | Each channel-tab page costs **5 credits**. Failed requests are not charged. # Community Post Source: https://docs.scrapebadger.com/api-reference/endpoint/youtube/community-post GET /v1/youtube/posts/{post_id} Detail for a single YouTube community post (text, poll, image, or shared content). ## Path Parameters The community post id (the `lc=`/`Ug…` value from a `/post/{id}` URL). ## Response The community post id. Full URL to the post (nullable). Post type: `text`, `poll`, `image`, `video`, or `shared` (nullable). Post body text (nullable). Links parsed from the post text. Author channel id (nullable). Author channel name (nullable). Author channel URL (nullable). Author avatar URL (nullable). Relative publish time, e.g. `2 days ago` (nullable). Unix publish timestamp (nullable). Number of likes (nullable). Like count as displayed (nullable). Number of comments (nullable). Poll options (poll posts only). Option text (nullable). Vote share as a percentage (nullable). Vote count (nullable). Option image URL, for image polls (nullable). Total votes cast (poll posts only, nullable). Attached images, with `url`, `width`, `height`. Attached video object, if any (nullable). The original post, for shared posts (nullable). ISO 8601 timestamp when the post was scraped. Unix timestamp when the post was scraped. ### Example Response ```json theme={null} { "post_id": "UgkxAbCdEfGhIjKlMnOpQrStUvWxYz", "post_url": "https://www.youtube.com/post/UgkxAbCdEfGhIjKlMnOpQrStUvWxYz", "post_type": "poll", "text": "Which video should we make next?", "channel_id": "UCBR8-60-B28hp2BmDPdntcQ", "channel_name": "YouTube", "published_time_text": "2 days ago", "like_count": 18200, "comment_count": 940, "poll_choices": [ { "text": "Behind the scenes", "percentage": 62.0, "votes": 31000 }, { "text": "Q&A", "percentage": 38.0, "votes": 19000 } ], "poll_total_votes": 50000, "images": [], "scraped_at": "2026-06-21T12:00:00Z" } ``` ## Post Comments To page the comments on a community post, call: ```bash theme={null} curl "https://scrapebadger.com/v1/youtube/posts/UgkxAbCdEfGhIjKlMnOpQrStUvWxYz/comments" \ -H "X-API-Key: YOUR_API_KEY" ``` This returns a `CommentsResponse` (the same `comments` + `continuation` shape as [video comments](/api-reference/endpoint/youtube/video-comments)). A community-post request and a post-comments page each cost **5 credits**. Failed requests are not charged. # Get Video Source: https://docs.scrapebadger.com/api-reference/endpoint/youtube/get-video GET /v1/youtube/videos/{video_id} Full detail for a single YouTube video (metadata, engagement, chapters, heatmap, live details, ...). ## Path Parameters The YouTube video id (the 11-character `v=` value, e.g. `dQw4w9WgXcQ`). ## Query Parameters Content region (ISO 3166-1 alpha-2). Examples: `US`, `GB`, `DE`, `JP`. UI / interface language (BCP-47). Examples: `en`, `de`, `fr`, `ja`. ## Response The YouTube video id. Video title. Full watch URL. Full video description (nullable). Links extracted from the description. Duration in seconds (nullable). Duration as `HH:MM:SS` (nullable). View count (nullable). View count as displayed (nullable). Like count (nullable). Like count as displayed (nullable). Comment count (nullable). Dislike count — private platform-wide since 2021, always `null`. Uploader channel id (nullable). Uploader channel name (nullable). Uploader `@handle` (nullable). Uploader channel URL (nullable). Uploader avatar URL (nullable). Whether the channel is verified (nullable). Whether the channel is an official artist channel (nullable). Channel subscriber count (nullable). Subscriber count as displayed (nullable). ISO 8601 publish timestamp (nullable). Unix publish timestamp (nullable). ISO 8601 upload timestamp (nullable). Unix upload timestamp (nullable). Relative publish text, e.g. `13 years ago` (nullable). Video keywords. Video tags. Hashtags used in the video. Category name (nullable). Category id (nullable). Wikipedia topic URLs (official-API only; usually empty). Thumbnail objects with `url`, `width`, `height`. Best/primary thumbnail URL (nullable). Storyboard spec, if present (nullable). Video chapters. Chapter title. Chapter start offset in seconds. Chapter start as displayed. Chapter thumbnail URL (nullable). Most-replayed graph points. Marker start offset in seconds. Marker duration in seconds. Normalized replay intensity (0.0-1.0). Whether the video is/was a live broadcast (nullable). Whether the stream is currently live (nullable). Whether it is an upcoming premiere/stream (nullable). Live/premiere timing with `actual_start_at`, `scheduled_start_at`, `concurrent_viewers`, `active_live_chat_id` (nullable). Whether the video is family-safe (nullable). Whether age-restricted (nullable). Whether members-only (nullable). Whether unlisted (nullable). Whether private (nullable). Whether the video is a Short (nullable). Whether the video is monetized (nullable). Whether comments are disabled (nullable). Whether the video declares paid placement (nullable). ISO country codes where the video is available. Region restriction with `allowed` and `blocked` country lists (nullable). Playability status, e.g. `OK` (nullable). `hd` or `sd` (nullable). `2d` or `3d` (nullable). `rectangular` or `360` (nullable). Whether captions exist (nullable). Available caption language codes. Product shelf entries with `title`, `price`, `vendor`, `thumbnail`, `link`. Related video objects (also available via `/related`). Token to page related videos (nullable). Sound id (Shorts, nullable). Sound title (Shorts, nullable). Streaming data — only populated when requested via `/streams` (nullable). Embeddable player URL (nullable). ISO 8601 timestamp when the video was scraped. Unix timestamp when the video was scraped. ### Example Response ```json theme={null} { "video_id": "dQw4w9WgXcQ", "title": "Rick Astley - Never Gonna Give You Up (Official Video)", "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "description": "The official video for “Never Gonna Give You Up” by Rick Astley...", "length_seconds": 213, "duration": "00:03:33", "view_count": 1600000000, "view_count_text": "1.6B views", "like_count": 18000000, "comment_count": 2400000, "dislike_count": null, "channel_id": "UCuAXFkgsw1L7xaCfnd5JJOw", "channel_name": "Rick Astley", "channel_username": "@RickAstleyYT", "channel_is_verified": true, "number_of_subscribers": 4200000, "published_at": "2009-10-25T00:00:00Z", "published_time_text": "13 years ago", "keywords": ["rick astley", "never gonna give you up"], "hashtags": ["#RickAstley"], "category": "Music", "category_id": "10", "thumbnail": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", "chapters": [], "heatmap": [{ "start_seconds": 0.0, "duration_seconds": 2.13, "intensity": 1.0 }], "is_live_content": false, "is_family_safe": true, "captions_available": true, "caption_languages": ["en", "es", "fr"], "definition": "hd", "scraped_at": "2026-06-21T12:00:00Z" } ``` ## Related Endpoints | Endpoint | Description | | - | - | | `GET /v1/youtube/videos/{video_id}/related` | Related / recommended videos (returns `results` + `continuation`). | | `GET /v1/youtube/videos/{video_id}/streams` | Streaming formats (muxed + adaptive); `client` selects `IOS` (default), `ANDROID`, or `WEB`. **15 credits.** | | `GET /v1/youtube/videos/{video_id}/live_chat` | Live chat / chat replay messages (`continuation` paginated). | | `POST /v1/youtube/videos/batch` | Up to 50 video ids in one request (body `{ "video_ids": [...] }`); billed **10 credits per video**. | A video-detail request costs **10 credits**. The `/streams` sub-endpoint costs **15 credits**; `/related` and `/live_chat` cost **5 credits** each. Failed requests are not charged. **Stream URLs are best-effort and exit-bound.** YouTube signs each media URL with the IP that fetched it (`ip=` in the query string) and enforces that binding on some CDN nodes, so a URL that plays from one host may return `403` from another. Fetch promptly — they carry a short `expires_in_seconds` — and treat a `403` as "re-request the streams", not as an outage. Videos YouTube serves no playable formats for (unavailable, private, or app-gated) return `404`, and are not charged. # Hashtag Videos Source: https://docs.scrapebadger.com/api-reference/endpoint/youtube/hashtag GET /v1/youtube/hashtags/{tag} Videos published under a YouTube hashtag, paginated by continuation token. ## Path Parameters The hashtag, without the leading `#` (e.g. `shorts`, `lofi`). ## Query Parameters Content region (ISO 3166-1 alpha-2). Examples: `US`, `GB`, `DE`, `JP`. UI / interface language (BCP-47). Examples: `en`, `de`, `fr`, `ja`. Continuation token from a previous response to fetch the next page. ## Response The hashtag that was queried. Array of videos under the hashtag (polymorphic `SearchResult` shape). Result type, e.g. `video` or `short`. Video id (nullable). Video title (nullable). Full watch URL (nullable). Best thumbnail URL (nullable). Human-readable duration (nullable). Duration in seconds (nullable). View count (nullable). View count as displayed (nullable). Relative publish time (nullable). Uploader channel id (nullable). Uploader channel name (nullable). Whether the channel is verified (nullable). Whether the item is a Short (nullable). Token to fetch the next page (nullable when no more pages). ### Example Response ```json theme={null} { "tag": "lofi", "results": [ { "type": "video", "video_id": "jfKfPfyJRdk", "title": "lofi hip hop radio - beats to relax/study to", "url": "https://www.youtube.com/watch?v=jfKfPfyJRdk", "thumbnail": "https://i.ytimg.com/vi/jfKfPfyJRdk/hqdefault.jpg", "view_count_text": "Live · 42K watching", "published_time_text": "Streamed 2 years ago", "channel_name": "Lofi Girl", "channel_is_verified": true, "is_short": false } ], "continuation": "4qmFsgKQARIaRkVoYXNodGFn..." } ``` Each hashtag request costs **5 credits**. Failed requests are not charged. # Music Search Source: https://docs.scrapebadger.com/api-reference/endpoint/youtube/music-search GET /v1/youtube/music/search Search YouTube Music for songs, videos, albums, artists, and playlists. ## Query Parameters Search keywords. Content region (ISO 3166-1 alpha-2). Examples: `US`, `GB`, `DE`, `JP`. UI / interface language (BCP-47). Examples: `en`, `de`, `fr`, `ja`. Continuation token from a previous response to fetch the next page. ## Response The search query that was executed. Array of YouTube Music results (polymorphic `SearchResult` shape, keyed by `type`). Result type, e.g. `video`, `channel` (artist), or `playlist` (album). Track / video id (nullable). Track or item title (nullable). Full URL to the item (nullable). Best thumbnail / cover art URL (nullable). Human-readable duration (nullable). Duration in seconds (nullable). Play / view count as displayed (nullable). Artist channel id (nullable). Artist / uploader name (nullable). Whether the artist channel is verified (nullable). Album / playlist id (playlist results, nullable). Track count (album / playlist results, nullable). Token to fetch the next page (nullable when no more pages). ### Example Response ```json theme={null} { "query": "never gonna give you up", "results": [ { "type": "video", "video_id": "dQw4w9WgXcQ", "title": "Never Gonna Give You Up", "url": "https://music.youtube.com/watch?v=dQw4w9WgXcQ", "thumbnail": "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg", "duration": "3:33", "length_seconds": 213, "view_count_text": "1.6B plays", "channel_id": "UCuAXFkgsw1L7xaCfnd5JJOw", "channel_name": "Rick Astley", "channel_is_verified": true } ], "continuation": "EpcDEgxuZXZlciBnb25uYS..." } ``` Each music-search request costs **5 credits**. Failed requests are not charged. # Get Playlist Source: https://docs.scrapebadger.com/api-reference/endpoint/youtube/playlist GET /v1/youtube/playlists/{playlist_id} Full detail for a YouTube playlist plus the first page of its items. ## Path Parameters The YouTube playlist id (the `list=` value, e.g. `PLrAXtmErZgOeiKm4sgNOknGvNjby9efdf`). ## Query Parameters Content region (ISO 3166-1 alpha-2). Examples: `US`, `GB`, `DE`, `JP`. UI / interface language (BCP-47). Examples: `en`, `de`, `fr`, `ja`. ## Response The playlist id. Playlist title (nullable). Playlist description (nullable). Full playlist URL (nullable). Number of videos in the playlist (nullable). Total playlist views (nullable). Total views as displayed (nullable). When the playlist was last updated, as displayed (nullable). Owner channel id (nullable). Owner channel name (nullable). Owner channel URL (nullable). Whether the owner channel is verified (nullable). Playlist thumbnail variants with `url`, `width`, `height`. Best/primary thumbnail URL (nullable). Privacy status, e.g. `PUBLIC`, `UNLISTED` (nullable). Whether the playlist is an auto-generated mix (nullable). First page of playlist items. 1-based position in the playlist (nullable). Video id. Video title (nullable). Full watch URL (nullable). Duration in seconds (nullable). Human-readable duration (nullable). Uploader channel id (nullable). Uploader channel name (nullable). Uploader channel URL (nullable). Thumbnail variants with `url`, `width`, `height`. Best thumbnail URL (nullable). View count (nullable). View count as displayed (nullable). Relative publish time (nullable). Whether the item is currently playable (nullable). Per-playlist-entry id (nullable). Token to fetch the next page of items (nullable when no more pages). ISO 8601 timestamp when the playlist was scraped. Unix timestamp when the playlist was scraped. ### Example Response ```json theme={null} { "playlist_id": "PLrAXtmErZgOeiKm4sgNOknGvNjby9efdf", "title": "Top Music Videos", "description": "A rotating collection of the biggest music videos.", "playlist_url": "https://www.youtube.com/playlist?list=PLrAXtmErZgOeiKm4sgNOknGvNjby9efdf", "video_count": 50, "view_count": 12400000, "view_count_text": "12.4M views", "channel_id": "UCBR8-60-B28hp2BmDPdntcQ", "channel_name": "YouTube", "channel_is_verified": true, "thumbnail": "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg", "privacy_status": "PUBLIC", "is_mix": false, "videos": [ { "position": 1, "video_id": "dQw4w9WgXcQ", "title": "Rick Astley - Never Gonna Give You Up (Official Video)", "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ&list=PLrAXtmErZgOeiKm4sgNOknGvNjby9efdf", "length_seconds": 213, "duration": "3:33", "channel_name": "Rick Astley", "view_count": 1600000000, "is_playable": true } ], "continuation": "4qmFsgJhEiRWTFBM...", "scraped_at": "2026-06-21T12:00:00Z" } ``` Paginate the remaining items with [`/v1/youtube/playlists/{playlist_id}/items`](/api-reference/endpoint/youtube/playlist-items) using the returned `continuation` token. Auto-generated mixes are available at `GET /v1/youtube/mixes/{mix_id}` and return the same `Playlist` shape with `is_mix: true`. A playlist (or mix) request costs **5 credits**. Failed requests are not charged. # Playlist Items Source: https://docs.scrapebadger.com/api-reference/endpoint/youtube/playlist-items GET /v1/youtube/playlists/{playlist_id}/items A continuation page of items within a YouTube playlist. ## Path Parameters The YouTube playlist id (the `list=` value). ## Query Parameters Continuation token from a previous [playlist](/api-reference/endpoint/youtube/playlist) or playlist-items response. Omit it to fetch the first page. ## Response The playlist id the items belong to. Array of playlist items. 1-based position in the playlist (nullable). Video id. Video title (nullable). Full watch URL (nullable). Duration in seconds (nullable). Human-readable duration (nullable). Uploader channel id (nullable). Uploader channel name (nullable). Uploader channel URL (nullable). Thumbnail variants with `url`, `width`, `height`. Best thumbnail URL (nullable). View count (nullable). View count as displayed (nullable). Relative publish time (nullable). Whether the item is currently playable (nullable). Per-playlist-entry id (nullable). Token to fetch the next page (nullable when no more pages). ### Example Response ```json theme={null} { "playlist_id": "PLrAXtmErZgOeiKm4sgNOknGvNjby9efdf", "items": [ { "position": 101, "video_id": "9bZkp7q19f0", "title": "PSY - GANGNAM STYLE", "url": "https://www.youtube.com/watch?v=9bZkp7q19f0&list=PLrAXtmErZgOeiKm4sgNOknGvNjby9efdf", "length_seconds": 252, "duration": "4:12", "channel_name": "officialpsy", "view_count": 5100000000, "is_playable": true, "set_video_id": "PLrAXtmErZgOeiKm4sgNOknGvNjby9efdf9bZkp7q19f0" } ], "continuation": "4qmFsgJhEiRWTFBMckFY..." } ``` Each playlist-items page costs **5 credits**. Failed requests are not charged. # Resolve Channel Source: https://docs.scrapebadger.com/api-reference/endpoint/youtube/resolve-channel GET /v1/youtube/channels/resolve Resolve a YouTube handle, custom URL, or any YouTube URL to its canonical channel / video / playlist ids. ## Query Parameters A YouTube `@handle` or custom URL slug to resolve (e.g. `@YouTube`, `youtube`). Provide either `handle` or `url`. Any YouTube URL to resolve (channel, video, or playlist). Provide either `handle` or `url`. ## Response The handle or URL that was resolved. Resolved entity type: `channel`, `video`, or `playlist` (nullable). Canonical channel id, if applicable (nullable). Channel `@handle`, if applicable (nullable). Video id, if the input resolved to a video (nullable). Playlist id, if the input resolved to a playlist (nullable). The canonical URL of the resolved entity (nullable). ### Example Response ```json theme={null} { "input": "@YouTube", "type": "channel", "channel_id": "UCBR8-60-B28hp2BmDPdntcQ", "channel_username": "@YouTube", "video_id": null, "playlist_id": null, "canonical_url": "https://www.youtube.com/channel/UCBR8-60-B28hp2BmDPdntcQ" } ``` A resolve request costs **2 credits**. Failed requests are not charged. ## Reference & Utility Endpoints These low-cost helper endpoints share this section. ### oEmbed `GET /v1/youtube/oembed?url=...` returns YouTube's public oEmbed metadata for a video or playlist URL — `title`, `author_name`, `author_url`, `thumbnail_url`, `html` embed snippet, and dimensions. **Costs 1 credit.** ```json theme={null} { "type": "video", "version": "1.0", "title": "Rick Astley - Never Gonna Give You Up (Official Video)", "author_name": "Rick Astley", "author_url": "https://www.youtube.com/@RickAstleyYT", "provider_name": "YouTube", "thumbnail_url": "https://i.ytimg.com/vi/dQw4w9WgXcQ/hqdefault.jpg", "html": "", "width": 480, "height": 270 } ``` ### Categories `GET /v1/youtube/categories?gl=US` returns the video category reference list for a region. Each row has `id` and `title`. **Free (0 credits).** ```json theme={null} { "gl": "US", "categories": [ { "id": "10", "title": "Music" }, { "id": "20", "title": "Gaming" } ] } ``` ### Languages `GET /v1/youtube/languages` returns the supported UI languages (valid `hl` values), each with `id` (code) and `title`. **Free (0 credits).** ```json theme={null} { "languages": [ { "id": "en", "title": "English" }, { "id": "de", "title": "German" } ] } ``` ### Regions `GET /v1/youtube/regions` returns the supported content regions (valid `gl` values), each with `id` (code) and `title`. **Free (0 credits).** ```json theme={null} { "regions": [ { "id": "US", "title": "United States" }, { "id": "GB", "title": "United Kingdom" } ] } ``` ### Markets `GET /v1/youtube/markets` returns the supported markets reference (region + language pairings). **Free (0 credits).** oEmbed costs **1 credit**; categories, languages, regions, and markets are **free** reference endpoints (0 credits). Failed requests are not charged. # Search Source: https://docs.scrapebadger.com/api-reference/endpoint/youtube/search GET /v1/youtube/search Search YouTube for videos, channels, playlists, or movies. ## Query Parameters Search keywords. Restrict results to a single result type. | Value | Description | | - | - | | `all` | All result types (default) | | `video` | Videos only | | `channel` | Channels only | | `playlist` | Playlists only | | `movie` | Movies only | Sort order for results. | Value | Description | | - | - | | `relevance` | Best match (default) | | `date` | Most recently uploaded | | `views` | Most viewed | | `rating` | Highest rated | Filter by upload recency: `hour`, `today`, `week`, `month`, or `year`. Filter by video length: `short` (\< 4 min), `medium` (4-20 min), or `long` (> 20 min). Comma-separated feature filters, e.g. `hd,4k,subtitles,live,creative_commons`. Content region (ISO 3166-1 alpha-2 country code). Examples: `US`, `GB`, `DE`, `JP`. UI / interface language (BCP-47). Examples: `en`, `de`, `fr`, `ja`. Continuation token from a previous response to fetch the next page. ## Response The search query that was executed. Array of matching results (polymorphic, keyed by `type`). Result type: `video`, `channel`, `playlist`, `movie`, or `short`. Position on the page (nullable). Video id (video/short/movie results, nullable). Result title (nullable). Full URL to the result (nullable). Thumbnail objects with `url`, `width`, `height`. Best/primary thumbnail URL (nullable). Human-readable duration, e.g. `3:32` (nullable). Duration in seconds (nullable). View count (nullable). View count as displayed, e.g. `1.6B views` (nullable). Abbreviated view count (nullable). Relative publish time, e.g. `13 years ago` (nullable). ISO 8601 publish timestamp (nullable). Unix publish timestamp (nullable). Short description snippet (nullable). Result badges, e.g. `4K`, `CC`. Extra metadata strings. Whether the video is live (nullable). Whether the result is a Short (nullable). Whether the video is members-only (nullable). Associated channel id (nullable). Channel name (nullable). Channel URL (nullable). Channel avatar URL (nullable). Whether the channel is verified (nullable). Subscriber count text (channel results, nullable). Subscriber count (channel results, nullable). Video count text (channel results, nullable). Channel `@handle` (channel results, nullable). Whether the channel is verified (channel results, nullable). Playlist id (playlist results, nullable). Number of videos (playlist results, nullable). First video id (playlist results, nullable). Reported total result count (nullable). Estimated result count (nullable). Filter chips / refinements with `title`, `is_selected`, `continuation`. Spelling suggestion, if any (nullable). Corrected query actually searched (nullable). Suggested query refinements. Related search objects. Token to fetch the next page (nullable when no more pages). ### Example Response ```json theme={null} { "query": "lofi hip hop", "results": [ { "type": "video", "position": 1, "video_id": "jfKfPfyJRdk", "title": "lofi hip hop radio - beats to relax/study to", "url": "https://www.youtube.com/watch?v=jfKfPfyJRdk", "thumbnail": "https://i.ytimg.com/vi/jfKfPfyJRdk/hqdefault.jpg", "duration": null, "view_count_text": "Live · 42K watching", "published_time_text": "Streamed 2 years ago", "channel_id": "UCSJ4gkVC6NrvII8umztf0Ow", "channel_name": "Lofi Girl", "channel_is_verified": true, "is_live": true, "is_short": false } ], "estimated_results": 1240000, "chips": [ { "title": "All", "is_selected": true, "continuation": null }, { "title": "Videos", "is_selected": false, "continuation": "EgIQAQ..." } ], "continuation": "EpcDEgxsb2ZpIGhpcCBob3A..." } ``` Each search request costs **5 credits**. Failed requests are not charged. # Get Short Source: https://docs.scrapebadger.com/api-reference/endpoint/youtube/short GET /v1/youtube/shorts/{video_id} Full detail for a single YouTube Short (vertical reel), including its sound. ## Path Parameters The Shorts video id (the id from a `/shorts/{id}` URL, e.g. `aBcD1234efg`). ## Query Parameters Content region (ISO 3166-1 alpha-2). Examples: `US`, `GB`, `DE`, `JP`. UI / interface language (BCP-47). Examples: `en`, `de`, `fr`, `ja`. ## Response A Short is a `Video` with `is_short: true` plus a Shorts-specific vertical thumbnail and sound fields. The full field set matches [Get Video](/api-reference/endpoint/youtube/get-video); the most relevant Shorts fields are listed below. The Shorts video id. Short title (nullable). Full watch URL (nullable). Short description (nullable). Duration in seconds (nullable). View count (nullable). Like count (nullable). Comment count (nullable). Uploader channel id (nullable). Uploader channel name (nullable). Uploader `@handle` (nullable). Whether the channel is verified (nullable). ISO 8601 publish timestamp (nullable). Hashtags used in the Short. Best/primary thumbnail URL (nullable). Vertical (portrait) thumbnail URL (nullable). Always `true` for Shorts. Sound id used by the Short (nullable). Sound title (nullable). Sound artist (nullable). ISO 8601 timestamp when the Short was scraped. ### Example Response ```json theme={null} { "video_id": "aBcD1234efg", "title": "60-second pasta hack #shorts", "url": "https://www.youtube.com/shorts/aBcD1234efg", "length_seconds": 58, "view_count": 8200000, "like_count": 410000, "comment_count": 3200, "channel_id": "UCabc123", "channel_name": "Quick Recipes", "channel_username": "@QuickRecipes", "channel_is_verified": true, "published_at": "2026-05-30T00:00:00Z", "hashtags": ["#shorts", "#cooking"], "thumbnail": "https://i.ytimg.com/vi/aBcD1234efg/hqdefault.jpg", "thumbnail_vertical": "https://i.ytimg.com/vi/aBcD1234efg/oardefault.jpg", "is_short": true, "sound_id": "MPSDxyz123", "sound_title": "Original audio", "sound_artist": "Quick Recipes", "scraped_at": "2026-06-21T12:00:00Z" } ``` ## Shorts by Sound To list Shorts that use a given sound, call: ```bash theme={null} curl "https://scrapebadger.com/v1/youtube/shorts/by_sound/MPSDxyz123" \ -H "X-API-Key: YOUR_API_KEY" ``` This returns an `items` array of Shorts plus a `continuation` token for pagination. A Short-detail request and a shorts-by-sound page each cost **5 credits**. Failed requests are not charged. # Trending Source: https://docs.scrapebadger.com/api-reference/endpoint/youtube/trending GET /v1/youtube/trending YouTube trending feed for a region — Now, Music, Gaming, or Movies. ## Query Parameters Content region (ISO 3166-1 alpha-2) whose trending feed to fetch. Examples: `US`, `GB`, `DE`, `JP`. UI / interface language (BCP-47). Examples: `en`, `de`, `fr`, `ja`. Which trending tab to return. | Value | Description | | - | - | | `now` | Trending now (default) | | `music` | Trending music | | `gaming` | Trending gaming | | `movies` | Trending movies | Continuation token from a previous response to fetch the next page. ## Response The region the feed was fetched for (nullable). The trending tab that was returned (nullable). Array of trending items. Position in the feed (nullable). Source category, e.g. `Now`, `Music`, `Gaming` (nullable). Video id (nullable). Video title (nullable). Full watch URL (nullable). Thumbnail variants with `url`, `width`, `height`. Best thumbnail URL (nullable). Human-readable duration (nullable). Duration in seconds (nullable). View count (nullable). View count as displayed (nullable). Relative publish time (nullable). Short description snippet (nullable). Uploader channel id (nullable). Uploader channel name (nullable). Uploader channel URL (nullable). Uploader avatar URL (nullable). Whether the channel is verified (nullable). Item badges. Whether the item is live (nullable). Whether the item is a Short (nullable). Token to fetch the next page (nullable when no more pages). ### Example Response ```json theme={null} { "gl": "US", "type": "now", "items": [ { "position": 1, "category": "Now", "video_id": "abc123XYZ_0", "title": "The video everyone is watching today", "url": "https://www.youtube.com/watch?v=abc123XYZ_0", "thumbnail": "https://i.ytimg.com/vi/abc123XYZ_0/hqdefault.jpg", "duration": "12:08", "view_count": 4200000, "view_count_text": "4.2M views", "published_time_text": "18 hours ago", "channel_name": "Trending Creator", "channel_is_verified": true, "is_live": false } ], "continuation": "4qmFsgKZARIYRkV0cmVuZGlu..." } ``` ## Related Feeds | Endpoint | Returns | | - | - | | `GET /v1/youtube/trending/shorts` | The trending Shorts shelf (`items` of Shorts). | | `GET /v1/youtube/home` | The guest home / recommendations feed (`HomeResponse`). | Each trending or home request costs **5 credits**. Failed requests are not charged. # Video Comments Source: https://docs.scrapebadger.com/api-reference/endpoint/youtube/video-comments GET /v1/youtube/videos/{video_id}/comments Top-level comments for a YouTube video, paginated by continuation token. ## Path Parameters The YouTube video id (e.g. `dQw4w9WgXcQ`). ## Query Parameters Comment sort order. | Value | Description | | - | - | | `top` | Top comments (default) | | `newest` | Newest first | Continuation token from a previous response to fetch the next page of comments. ## Response The video the comments belong to. Array of top-level comments. Unique comment id. Comment text (nullable). Relative publish time, e.g. `2 weeks ago` (nullable). Unix publish timestamp (nullable). Author display name (nullable). Author channel id (nullable). Author channel URL (nullable). Author avatar URL (nullable). Whether the author is verified (nullable). Whether the author is an official artist (nullable). Whether the author is the video's uploader (nullable). Author badges (e.g. member badges). Number of likes (nullable). Number of replies (nullable). Whether the creator hearted the comment (nullable). Whether the comment is pinned (nullable). Whether the comment is a reply (nullable). Parent comment id, if a reply (nullable). Token to fetch this comment's replies (nullable). Super Thanks purchase amount, if any (nullable). The video id the comment belongs to (nullable). Total comment count on the video (nullable). Sort options with `title` and `token` (e.g. `top`, `newest`). Token to fetch the next page (nullable when no more pages). ### Example Response ```json theme={null} { "video_id": "dQw4w9WgXcQ", "comments": [ { "comment_id": "UgxKREWxIgDrw8w2e_Z4AaABAg", "text": "Who's still listening in 2026?", "published_time_text": "3 days ago", "author": "@musiclover", "author_channel_id": "UCabc123", "author_is_verified": false, "like_count": 1820, "reply_count": 42, "is_pinned": false, "is_reply": false, "replies_continuation": "Eg0SC2RRdzR3OVdnWGNR..." } ], "comment_count": 2400000, "sorting_tokens": [ { "title": "Top comments", "token": "..." }, { "title": "Newest first", "token": "..." } ], "continuation": "Eg0SC2RRdzR3OVdnWGNRGAYyJg..." } ``` ## Replies To fetch replies to a specific comment, call: ```bash theme={null} curl "https://scrapebadger.com/v1/youtube/videos/dQw4w9WgXcQ/comments/UgxKREWxIgDrw8w2e_Z4AaABAg/replies" \ -H "X-API-Key: YOUR_API_KEY" ``` This returns a `RepliesResponse` with `comment_id`, a `replies` array (same `Comment` shape), and a `continuation` token. You can also pass the `replies_continuation` value from a comment directly as the `continuation` query parameter. Each comments page and each replies page costs **5 credits**. Failed requests are not charged. # Video Transcript Source: https://docs.scrapebadger.com/api-reference/endpoint/youtube/video-transcript GET /v1/youtube/videos/{video_id}/transcript Timed transcript for a YouTube video, with ready-to-use SRT, VTT, and plain-text exports. ## Path Parameters The YouTube video id (e.g. `dQw4w9WgXcQ`). ## Query Parameters Preferred transcript language code (e.g. `en`, `de`). Falls back to the default available track. Track type preference: `manual` (human-authored) or `asr` (auto-generated). ## Response The video the transcript belongs to. Language code of the returned transcript (nullable). Human-readable language name (nullable). Track type: `manual` or `asr` (auto-generated) (nullable). Whether the track can be machine-translated (nullable). Other available transcript tracks (with language metadata). Languages the transcript can be translated into. Timed transcript lines. Segment start offset in milliseconds (nullable). Segment end offset in milliseconds (nullable). Segment duration in milliseconds (nullable). Start offset as displayed, e.g. `0:12` (nullable). The line text (nullable). The entire transcript as a single plain-text string (nullable). The transcript formatted as a ready-to-use SubRip (`.srt`) file (nullable). The transcript formatted as a ready-to-use WebVTT (`.vtt`) file (nullable). ### Example Response ```json theme={null} { "video_id": "dQw4w9WgXcQ", "language": "en", "language_name": "English", "type": "manual", "is_translatable": true, "available_transcripts": [ { "language": "en", "language_name": "English", "type": "manual" }, { "language": "es", "language_name": "Spanish", "type": "asr" } ], "segments": [ { "start_ms": 18000, "end_ms": 21000, "duration_ms": 3000, "start_time_text": "0:18", "text": "Never gonna give you up" }, { "start_ms": 21000, "end_ms": 24000, "duration_ms": 3000, "start_time_text": "0:21", "text": "Never gonna let you down" } ], "full_text": "Never gonna give you up Never gonna let you down ...", "srt": "1\n00:00:18,000 --> 00:00:21,000\nNever gonna give you up\n\n2\n00:00:21,000 --> 00:00:24,000\nNever gonna let you down\n", "vtt": "WEBVTT\n\n00:00:18.000 --> 00:00:21.000\nNever gonna give you up\n\n00:00:21.000 --> 00:00:24.000\nNever gonna let you down\n" } ``` ## Available Caption Tracks To list the caption tracks for a video without downloading the full transcript, call: ```bash theme={null} curl "https://scrapebadger.com/v1/youtube/videos/dQw4w9WgXcQ/captions" \ -H "X-API-Key: YOUR_API_KEY" ``` This returns a `CaptionsResponse` with `video_id`, a `tracks` array (each with `language`, `language_name`, `type`, `is_translatable`, `base_url`), and `translation_languages`. The captions endpoint costs **2 credits**. A transcript request costs **5 credits**; the `/captions` listing costs **2 credits**. Failed requests are not charged. # Location Suggestions Source: https://docs.scrapebadger.com/api-reference/endpoint/zillow/autocomplete GET /v1/zillow/autocomplete Autocomplete locations (cities, ZIPs, neighborhoods, addresses) for a partial query. ## Query Parameters Partial location to autocomplete — a city, ZIP, address, or neighborhood (e.g. `austi`, `9021`, `travis heights`). ## Response The query prefix that was autocompleted. Array of suggestion objects. Human-readable label, e.g. `Austin, TX` (nullable). Zillow region id — pass-through key for a region (nullable). Suggestion type, e.g. `city`, `zipcode`, `neighborhood`, `county`, `state` (nullable). Center latitude (nullable). Center longitude (nullable). Zillow property id — populated when the suggestion is a specific home (nullable). Metro area id (nullable). ### Example Response ```json theme={null} { "query": "austi", "results": [ { "display": "Austin, TX", "region_id": 10221, "region_type": "city", "latitude": 30.2672, "longitude": -97.7431, "zpid": null, "metro_id": 394355 } ] } ``` Each autocomplete request costs **2 credits**. Failed requests are not charged. # Get Agent Profile Source: https://docs.scrapebadger.com/api-reference/endpoint/zillow/get-agent GET /v1/zillow/agent Full detail for a Zillow real-estate professional — profile, reviews, past sales, licenses, and active listings. ## Query Parameters Provide **either** `username` or `url`. Zillow profile username (screen name), e.g. `jane-doe`. Taken from a `/profile//` URL. Full Zillow `/profile/...` URL (alternative to `username`). ## Response The response wraps a single `Agent` object under an `agent` key. Profile username (nullable). Zillow user id (nullable). Full name (nullable). Profile URL (nullable). Profile photo URL (nullable). Phone (nullable). Email (nullable). Business / brokerage name (nullable). Business address (nullable). Broker name (nullable). Title (nullable). Biography (nullable). Average review rating (nullable). Number of reviews (nullable). Recent sales count (nullable). Total sales in the last year (nullable). Active for-sale listings count (nullable). Active for-rent listings count (nullable). Past sales count (nullable). Years of experience (nullable). Top-agent flag (nullable). Team-lead flag (nullable). Primary license number (nullable). Primary license state (nullable). Personal website URL (nullable). Facebook URL (nullable). LinkedIn URL (nullable). X / Twitter URL (nullable). Intro video URL (nullable). Specialty tags (list of strings). Service area names (list of strings). Languages spoken (list of strings). Professional licenses. License state (nullable). License type (nullable). License number (nullable). License status (nullable). Expiration date (nullable). Raw professional-information label/value records. Agent reviews. Star rating (nullable). Review text (nullable). Raw date label (nullable). Date as a Unix timestamp (nullable). Date as an ISO-8601 string (nullable). Work described in the review (nullable). Reviewer name (nullable). Agent's response to the review (nullable). Category sub-ratings: `{ description, score }`. Closed transactions. Property id (nullable). Street line (nullable). City, state, ZIP (nullable). Sold price (nullable). Raw sold date label (nullable). Sold date as a Unix timestamp (nullable). Sold date as an ISO-8601 string (nullable). Bedrooms (nullable). Bathrooms (nullable). Interior area (nullable). Latitude (nullable). Longitude (nullable). Side represented: `buyer`, `seller`, or `both` (nullable). Photo URL (nullable). Listing URL (nullable). The agent's active listings — same shape as a search [`Listing`](/api-reference/endpoint/zillow/search) object. Scrape time as a Unix timestamp (nullable). Scrape time as an ISO-8601 string (nullable). ### Example Response ```json theme={null} { "agent": { "username": "jane-doe", "encoded_zuid": "X1-ZU10abcd1234_5xyz9", "name": "Jane Doe", "url": "https://www.zillow.com/profile/jane-doe/", "profile_photo": "https://photos.zillowstatic.com/h/p/jane.jpg", "phone": "512-555-0100", "business_name": "Downtown Realty Group", "title": "Real Estate Agent", "rating": 4.9, "review_count": 128, "recent_sales_count": 34, "years_experience": 12, "is_top_agent": true, "license_number": "0654321", "license_state": "TX", "specialties": ["Buyer's Agent", "Listing Agent"], "service_areas": ["Austin, TX", "Round Rock, TX"], "languages": ["English", "Spanish"], "licenses": [ { "state": "TX", "license_type": "Real Estate Agent", "license_number": "0654321", "status": "Active" } ], "reviews": [ { "rating": 5, "comment": "Fantastic to work with!", "reviewer_name": "buyer123", "work_description": "Helped me buy a home", "sub_ratings": [{ "description": "Responsiveness", "score": 5 }] } ], "past_sales": [ { "zpid": "29499726", "street_address": "123 Main St", "city_state_zip": "Austin, TX 78701", "price": 455000, "sold_date_at": "2026-03-15T00:00:00Z", "represented": "seller" } ], "listings": [ { "position": 1, "zpid": "30112233", "home_status": "FOR_SALE", "price": 525000, "beds": 4, "baths": 3, "city": "Austin", "state": "TX" } ], "scraped_at": "2026-07-07T12:00:00Z" } } ``` Each agent-profile request costs **5 credits**. Failed requests are not charged. # Get Multifamily Building Source: https://docs.scrapebadger.com/api-reference/endpoint/zillow/get-building GET /v1/zillow/building A Zillow apartment community — floor plans, per-unit rents, availability dates, amenities, schools and walk/transit scores. Zillow serves multi-unit rentals as **buildings**, not homes: they live on `/apartments/...` and `/b/...` URLs and embed a different data blob, so [Get Property Detail](/api-reference/endpoint/zillow/get-property) cannot read them (it answers `400 building_url` if you pass one). Pass the `detail_url` of any [search](/api-reference/endpoint/zillow/search) result whose `home_type` is `BUILDING` — `GET /v1/zillow/search?location=Kansas+City,+MO&status=for_rent` returns them. ## Query Parameters Full Zillow building URL, e.g. `https://www.zillow.com/apartments/kansas-city-mo/brookside-51/CkBJqt/`. A `/homedetails/...` URL is rejected with `400 not_a_building_url`. ## Response The response wraps a single `Building` object under a `building` key. Canonical building URL (nullable). Zillow's building id (nullable). Zillow id of the building's primary unit (nullable). Community name, e.g. `Brookside 51` (nullable). `FOR_RENT` (nullable). e.g. `["apartment"]`. Feed provider's listing id — joins to a search card's `provider_listing_id` (nullable). Street address (nullable). Full one-line address (nullable). City (nullable). State code (nullable). ZIP code (nullable). County (nullable). Country (nullable). Neighborhood (nullable). Latitude (nullable). Longitude (nullable). IANA time zone (nullable). Leasing-office phone (nullable). Property manager, e.g. `Greystar` (nullable). Whether Zillow accepts applications for this building (nullable). ISO 4217 currency code (nullable). Cheapest advertised total monthly price across the live inventory (nullable). Most expensive advertised total monthly price (nullable). Cheapest base rent — excludes mandatory monthly fees (nullable). Most expensive base rent (nullable). Whether the headline price already includes the required monthly fees (nullable). Units Zillow reports as available (nullable). Units in the building's feed (nullable). Marketing description (nullable). Verbatim summary facts, e.g. `["170 units", "built in 2018"]`. Building amenities. In-unit features. Parking and other policies. Highlighted features. Current move-in concessions. Leasing-office hours. Pet types allowed. Walk Score (nullable). Transit Score (nullable). Bike Score (nullable). Building is waitlisted (nullable). Income-restricted housing (nullable). Senior housing (nullable). Student housing (nullable). Floor-plan models: `name`, `beds`, `baths`, `sqft`, `price_min`/`price_max`, `base_rent_min`/`base_rent_max`, `required_monthly_fee_min`/`max`, `available_from_at`, `lease_term`, `description`, `photos[]`, `units[]`, `units_available`. Every unit across every floor plan, flattened: `unit_number`, `zpid`, `beds`, `baths`, `sqft`, `price`, `base_rent`, `required_monthly_fee_min`/`max`, `list_price_includes_required_fees`, `available_from_at`, `allowed_pets[]`. `name`, `rating`, `grades`, `level`, `type`, `distance`. `url`, `caption`, responsive `sources[]`. Scrape time, ISO-8601 (nullable). `price` is the total monthly leasing price Zillow advertises; `base_rent` excludes the mandatory monthly fees, which are carried in `required_monthly_fee_min`/`max`. For rent comps, compare `base_rent` across buildings — the fee bundle differs by operator. Some buildings — typically landlord-managed ones — publish floor-plan pricing without enumerating individual units. There `units` is empty and `rent_min`/`rent_max` come from the floor plans. ## Example ```json Response theme={null} { "building": { "url": "https://www.zillow.com/apartments/kansas-city-mo/brookside-51/CkBJqt/", "lot_id": "2750786886", "zpid": "2062673170", "name": "Brookside 51", "building_type": "FOR_RENT", "home_types": ["apartment"], "street_address": "5100 Oak St", "full_address": "5100 Oak St, Kansas City, MO 64112", "city": "Kansas City", "state": "MO", "zipcode": "64112", "county": "Jackson County", "neighborhood": "South Plaza", "latitude": 39.03416, "longitude": -94.58333, "phone": "(816) 608-6275", "contact_name": "Greystar", "currency": "USD", "rent_min": 2015, "rent_max": 2580, "base_rent_min": 1734, "base_rent_max": 2299, "list_price_includes_required_fees": true, "units_available": 5, "unit_count": 5, "building_details": ["170 units", "built in 2018"], "floor_plans": [ { "name": "B2 (1BR)", "beds": 1, "baths": 1, "sqft": 795, "price_min": 2015, "price_max": 2045, "base_rent_min": 1734, "base_rent_max": 1764, "available_from_at": "2026-09-26T07:00:00Z", "lease_term": "Available months 6,7,8,9,10,11,12,13,14,15", "units_available": 2, "units": [ { "unit_number": "Unit 243", "zpid": "2062673170", "beds": 1, "baths": 1, "sqft": 795, "price": 2015, "base_rent": 1734, "required_monthly_fee_min": 281, "required_monthly_fee_max": 281, "list_price_includes_required_fees": true, "available_from_at": "2026-10-28T07:00:00Z", "allowed_pets": ["Dogs", "Cats"] } ] } ], "amenities": ["Club House", "Fitness Center", "Lounge: TV Lounge", "In Unit: In-Home Washers & Dryers"], "unit_features": ["Dryer", "Washer", "High End Stainless Steel Appliances"], "policies": ["Covered Parking", "Surface Lot"], "special_offers": ["Preferred Employer Discount: Receive $340 off move-in costs."], "office_hours": ["Mon - Fri: 9:00AM - 6:00PM", "Sat: 10:00AM - 2:00PM", "Sun: Closed"], "allowed_pets": ["Cats", "Large dogs", "Small dogs"], "walk_score": 85, "transit_score": 56, "bike_score": 42, "schools": [ { "name": "Hale Cook Elementary", "rating": 8, "grades": "PK-6", "type": "PUBLIC", "distance": 2.8 } ], "photos": [ { "url": "https://photos.zillowstatic.com/fp/84cf-cc_ft_1536.webp", "caption": "Community photo" } ], "scraped_at": "2026-09-09T08:12:44Z" } } ``` Each building request costs **5 credits**. Failed requests are not charged. # Get Property Detail Source: https://docs.scrapebadger.com/api-reference/endpoint/zillow/get-property GET /v1/zillow/property/{zpid} Maximal detail for a single Zillow property — home facts, price/tax/Zestimate history, schools, agent, and mortgage rates. ## Path Parameters The Zillow property id (`zpid`). You can find it in search results (`zpid`) or extract it from a `/homedetails/...` URL (the `NNNNN_zpid` segment). You can also fetch a property by full URL: `GET /v1/zillow/property?url=`. ## Response The response wraps a single `Property` object under a `property` key. It carries \~99 top-level fields plus the nested blocks below. Zillow property id. Internal id (nullable). Full listing URL (nullable). Home status, e.g. `FOR_SALE`, `SOLD`, `PENDING` (nullable). Home type, e.g. `SINGLE_FAMILY`, `CONDO` (nullable). Property type (nullable). Listing type (nullable). Posting product type (nullable). Listing data source (nullable). MLS number (nullable). Parcel id (nullable). County FIPS code (nullable). Provider listing id (nullable). Broker id (nullable). Contingency type (nullable). Listing sub-type flags: `is_fsba`, `is_fsbo`, `is_foreclosure`, `is_bank_owned`, `is_for_auction`, `is_coming_soon`, `is_new_home`, `is_pending` (nullable). Current price in USD (nullable). ISO 4217 currency code (nullable). Lower bound of a price range (nullable). Monthly HOA fee (nullable). Property tax rate (nullable). Annual homeowners insurance estimate (nullable). Last sold price (nullable). Last sold date as a Unix timestamp (nullable). Last sold date as an ISO-8601 string (nullable). Signed price change amount (nullable). Price-change date as a Unix timestamp (nullable). Price-change date as an ISO-8601 string (nullable). Current Zestimate value (nullable). Current Rent Zestimate (nullable). Zestimate low bound as a percent (nullable). Zestimate high bound as a percent (nullable). Rent Zestimate low bound as a percent (nullable). Rent Zestimate high bound as a percent (nullable). Zestimate 30 days ago (nullable). Rent Zestimate 30 days ago (nullable). Tax-assessed value (nullable). Zestimate value-history series. Raw date label (nullable). Date as a Unix timestamp (nullable). Date as an ISO-8601 string (nullable). Zestimate value at the point (nullable). Number of bedrooms (nullable). Number of bathrooms (nullable). Interior area (nullable). Interior area units (nullable). Lot size (nullable). Lot area value (nullable). Lot area units (nullable). Year built (nullable). Move-in-ready flag (nullable). Move-in completion date (nullable). Latitude (nullable). Longitude (nullable). Street line (nullable). Abbreviated address (nullable). City (nullable). State code (nullable). ZIP code (nullable). County (nullable). Country code (nullable). IANA time zone (nullable). Neighborhood (nullable). Whether the address is withheld (nullable). Income-restricted flag (nullable). Days on Zillow (nullable). Human time-on-Zillow string (nullable). Page view count (nullable). Favorite/save count (nullable). Tour view count (nullable). Number of photos (nullable). Listing description (nullable). Owner's "what I love" note (nullable). Editorial insight tags (list of strings). Marketing name (nullable). Brokerage name (nullable). Showcase listing flag (nullable). VR model flag (nullable). 3D model flag (nullable). Virtual tour URL (nullable). Interactive floor plan URL (nullable). Street View image URL (nullable). Static map image URL (nullable). New-construction type (nullable). Builder name (nullable). Promotion headline (nullable). Promotion description (nullable). Whether a promotion is present (nullable). Structured address: `street_address`, `city`, `state`, `zipcode`, `community`, `subdivision`, `neighborhood` (nullable). High-value subset of Zillow's `resoFacts` MLS block (\~125 fields), grouped below (nullable). `bathrooms_full`, `bathrooms_half`, `bathrooms_three_quarter`, `bathrooms_one_quarter`. `stories`, `stories_decimal`, `levels`, `property_condition`, `architectural_style`, `structure_type`, `building_name`, `construction_materials[]`, `foundation_details[]`, `roof_type`, `year_built_effective`. `above_grade_finished_area`, `below_grade_finished_area`, `lot_size_dimensions`, `main_level_bedrooms`, `main_level_bathrooms`, `basement`, `has_basement`, `attic`. `heating[]`, `cooling[]`, `appliances[]`, `flooring[]`, `utilities[]`, `electric[]`, `gas[]`, `sewer[]`, `water_source[]`. `green_building_verification_type[]`, `green_energy_efficient[]`, `green_energy_generation[]`, `green_sustainability[]`, `green_water_conservation[]`. `interior_features[]`, `exterior_features[]`, `lot_features[]`, `community_features[]`, `accessibility_features[]`, `door_features[]`, `window_features[]`, `laundry_features[]`, `patio_and_porch_features[]`, `fencing[]`, `other_structures[]`, `view[]`, `has_view`, `waterfront_features[]`, `water_view`, `water_body_name`, `security_features[]`. `parking_features[]`, `parking_capacity`, `garage_parking_capacity`, `carport_parking_capacity`, `covered_parking_capacity`, `open_parking_capacity`, `has_attached_garage`, `has_garage`, `has_carport`, `has_open_parking`. `pool_features[]`, `has_private_pool`, `spa_features[]`, `fireplaces`, `fireplace_features[]`, `has_fireplace`. `association_name`, `association_name2`, `association_fee`, `association_fee2`, `association_fee_includes[]`, `association_amenities[]`, `association_phone`, `has_association`, `hoa_fee`, `hoa_fee_total`, `tax_annual_amount`, `price_per_square_foot`. `has_land_lease`, `land_lease_amount`, `land_lease_expiration_date`, `can_raise_horses`, `additional_parcels_description`, `road_surface_type[]`. `on_market_date`, `cumulative_days_on_market`, `offer_review_date`. `number_of_units_in_community`, `availability_date`, `lease_term`, `tenant_pays[]`, `has_pets_allowed`, `pets_max_weight`, `has_rent_control`. `elementary_school`, `middle_school`, `high_school`, `elementary_school_district`, `middle_school_district`, `high_school_district`. `parcel_number`, `subdivision_name`, `municipality`, `city_region`, `zoning`, `zoning_description`, `ownership`, `ownership_type`, `property_sub_type[]`, `special_listing_conditions`, `listing_terms`, `inclusions`, `exclusions`. `is_new_construction`, `is_senior_community`, `has_home_warranty`, `furnished`, `development_status`, `park_name`. `at_a_glance_facts[]`, `rooms[]` — label/value pairs Zillow ships verbatim. Listing-agent / broker attribution (from `attributionInfo`). Listing agent name (nullable). Listing agent phone (nullable). Listing agent email (nullable). Listing agent license number (nullable). Co-agent name (nullable). Co-agent phone (nullable). Co-agent license number (nullable). Broker name (nullable). Broker phone (nullable). Buyer agent name (nullable). Buyer brokerage name (nullable). MLS id (nullable). MLS name (nullable). MLS disclaimer text (nullable). Listing agreement type (nullable). Attribution contact (nullable). Provider logo URL (nullable). True listing status (nullable). Last-checked timestamp (nullable). Last-updated timestamp (nullable). Raw listing-agent records. Raw listing-office records. Current mortgage rates: `fifteen_year_fixed`, `thirty_year_fixed`, `arm_5`, each `{ rate, rate_source, last_updated_utc, last_updated_at }` (nullable). Price / listing events over time. Raw date label (nullable). Event date as a Unix timestamp (nullable). Event date as an ISO-8601 string (nullable). Event type, e.g. `Listed for sale`, `Price change`, `Sold` (nullable). Price at the event (nullable). Price per sqft at the event (nullable). Price change rate (nullable). Event source (nullable). Buyer agent (nullable). Seller agent (nullable). Whether the event was a rental posting (nullable). Yearly tax records. Tax year as a Unix timestamp (nullable). Tax year as an ISO-8601 string (nullable). Assessed value (nullable). Assessed-value increase rate (nullable). Tax paid (nullable). Tax increase rate (nullable). Nearby schools. School name (nullable). GreatSchools rating (nullable). Grade range, e.g. `K-5` (nullable). Level, e.g. `Elementary`, `Middle`, `High`, `Primary` (nullable). Type, e.g. `Public`, `Private`, `Charter` (nullable). Distance from the property in miles (nullable). School profile URL (nullable). Student count (nullable). Whether the school is assigned to this home (nullable). Photo objects: `url`, `caption`, `subject_type`, and responsive `sources[]` (`{ url, width, format }`). Open-house objects: `start_utc`, `start_at`, `end_utc`, `end_at`, `note`. Linked nearby cities: `name`, `region_type`, `url`. Linked nearby neighborhoods: `name`, `region_type`, `url`. Linked nearby ZIP codes: `name`, `region_type`, `url`. Nearby homes (usually empty in server-rendered JSON; same shape as a search `Listing`). Scrape time as a Unix timestamp (nullable). Scrape time as an ISO-8601 string (nullable). ### Example Response ```json theme={null} { "property": { "zpid": "29499726", "url": "https://www.zillow.com/homedetails/123-Main-St-Austin-TX-78701/29499726_zpid/", "home_status": "FOR_SALE", "home_type": "SINGLE_FAMILY", "price": 460000, "currency": "USD", "monthly_hoa_fee": 45, "zestimate": 468000, "rent_zestimate": 2600, "tax_assessed_value": 420000, "bedrooms": 3, "bathrooms": 2, "living_area": 1800, "lot_size": 6500, "year_built": 2015, "street_address": "123 Main St", "city": "Austin", "state": "TX", "zipcode": "78701", "county": "Travis", "latitude": 30.2672, "longitude": -97.7431, "photo_count": 32, "description": "Charming single-family home in the heart of downtown...", "home_insights": ["Hardwood floors", "Updated kitchen"], "home_facts": { "bathrooms_full": 2, "stories": 2, "architectural_style": "Traditional", "heating": ["Central"], "cooling": ["Central Air"], "appliances": ["Dishwasher", "Refrigerator"], "has_garage": true, "parcel_number": "0203040506", "tax_annual_amount": 6200 }, "agent": { "agent_name": "Jane Doe", "agent_phone": "512-555-0100", "broker_name": "Downtown Realty Group", "mls_id": "ACT1234567", "mls_name": "ACTRIS" }, "mortgage_rates": { "thirty_year_fixed": { "rate": 6.8, "rate_source": "Zillow" } }, "price_history": [ { "date_at": "2026-06-01T00:00:00Z", "event": "Listed for sale", "price": 460000, "price_per_square_foot": 256 } ], "tax_history": [ { "year_at": "2024-01-01T00:00:00Z", "value": 420000, "tax_paid": 6200 } ], "zestimate_history": [ { "date_at": "2026-05-01T00:00:00Z", "value": 465000 } ], "schools": [ { "name": "Austin Elementary", "rating": 8, "grades": "K-5", "level": "Elementary", "type": "Public", "distance": 0.4, "assigned": true } ], "photos": [ { "url": "https://photos.zillowstatic.com/fp/abc-p_f.jpg", "caption": "Front", "sources": [{ "url": "https://photos.zillowstatic.com/fp/abc-p_e.webp", "width": 768, "format": "webp" }] } ], "scraped_at": "2026-07-07T12:00:00Z" } } ``` Each property-detail request costs **5 credits**. Failed requests are not charged. # List Markets Source: https://docs.scrapebadger.com/api-reference/endpoint/zillow/list-markets GET /v1/zillow/markets List Zillow's advertised coverage markets with their domain, currency, and locale. ## Response Array of advertised coverage markets. Informational only — Zillow serves all inventory from `zillow.com`, so there is no `market` routing parameter. Market code (`US` or `CA`). Portal domain (always `zillow.com`). ISO 3166-1 alpha-2 country code. ISO 4217 currency code (always `USD`). BCP-47 locale (always `en-US`). Market country name. ### Example Response ```json theme={null} { "markets": [ { "code": "US", "domain": "zillow.com", "country": "US", "currency": "USD", "locale": "en-US", "name": "United States" }, { "code": "CA", "domain": "zillow.com", "country": "CA", "currency": "USD", "locale": "en-US", "name": "Canada (MLS feed on zillow.com)" } ] } ``` Listing markets is a **free** reference endpoint (0 credits). # Search Properties Source: https://docs.scrapebadger.com/api-reference/endpoint/zillow/search GET /v1/zillow/search Search Zillow for for-sale / for-rent / sold listings with rich filters. ## Query Parameters Free-text location: a city ("Austin, TX"), a ZIP, an address, or a neighborhood. Listing status filter. | Value | Description | | - | - | | `for_sale` | Active for-sale listings (default) | | `for_rent` | Rental listings | | `sold` | Recently sold listings | Page number for paginated results. Zillow caps search at **20 pages (\~820 results)**. Range: `1` - `20`. Sort order for results. | Value | Description | | - | - | | `homes_for_you` | Best match | | `newest` | Most recently listed | | `price_high_to_low` | Most expensive first | | `price_low_to_high` | Cheapest first | | `bedrooms` | By bedroom count | | `bathrooms` | By bathroom count | | `square_feet` | By interior area | | `lot_size` | By lot size | | `year_built` | By year built | Minimum price in USD. Maximum price in USD. Minimum number of bedrooms. Range: `0` - `10`. Minimum number of bathrooms. Range: `0` - `10`. Comma-separated list of home types. Values: `houses`, `condos`, `townhomes`, `apartments`, `manufactured`, `lots`, `multi_family`. Minimum interior square footage. Maximum interior square footage. Minimum lot size in square feet. Maximum lot size in square feet. Earliest year built. Latest year built. Maximum monthly HOA fee. Match listing-description keywords. Days-on-Zillow filter (e.g. `1`, `7`, `30`). North latitude of a map-bounds box. **Power-user option** for tiling past the \~820-result cap. South latitude of a map-bounds box. East longitude of a map-bounds box. West longitude of a map-bounds box. ## Response The location that was searched. The status filter that was applied (`for_sale`, `for_rent`, `sold`). Total number of listings Zillow reports inside the map bounds (may exceed the page cap). The resolved region: `region_id` and `region_type`. Re-use `region_id` to tile or refine searches. The map bounding box the search covers: `north`, `east`, `south`, `west`. Subdivide this to beat the 820-result cap. Page-number pagination: `current_page`, `per_page`, `total_pages`, `total_results`. Scrape time as a Unix timestamp (nullable). Scrape time as an ISO-8601 string (nullable). Array of matching listing cards. 1-based position within the result set. Zillow property id — pass to the [property detail](/api-reference/endpoint/zillow/get-property) endpoint (nullable). Internal listing id (nullable). Full URL to the listing (nullable). Home type, e.g. `SINGLE_FAMILY`, `CONDO`, `TOWNHOUSE`, `APARTMENT` (nullable). Home status, e.g. `FOR_SALE`, `FOR_RENT`, `SOLD`, `PENDING` (nullable). Human status text, e.g. `House for sale` (nullable). Status type (nullable). Marketing status (nullable). Contingency type (nullable). Price in USD (nullable). Raw price string, e.g. `$460,000` or `$2,400/mo` (nullable). ISO 4217 currency code (nullable). Signed price change amount (nullable). Price-change date as a Unix timestamp (nullable). Price-change date as an ISO-8601 string (nullable). Price-reduction label (nullable). Marketing badge text, e.g. `Price cut` (nullable). Zillow value estimate (nullable). Zillow rent estimate (nullable). Tax-assessed value (nullable). Number of bedrooms (nullable). Number of bathrooms (nullable). Interior square footage (nullable). Lot size value (nullable). Lot size unit, e.g. `sqft`, `acres` (nullable). Full one-line address (nullable). Street line (nullable). Unit / apartment number (nullable). City (nullable). State code (nullable). ZIP code (nullable). Country code (nullable). Whether the address is withheld (nullable). Latitude (nullable). Longitude (nullable). Listing broker name (nullable). Provider listing id (nullable). Days on Zillow (nullable). Whether Zillow owns the home (nullable). Featured listing flag (nullable). Showcase listing flag (nullable). For-sale-by-agent flag (nullable). New-construction flag (nullable). Premier-builder flag (nullable). Pre-foreclosure / auction flag (nullable). Non-owner-occupied flag (nullable). Primary photo URL (nullable). Whether the listing has photos (nullable). Whether the listing has video (nullable). Whether the listing has a 3D model (nullable). Whether an open house is scheduled (nullable). Open-house start (nullable). Open-house end (nullable). Additional photo URLs. ### Example Response ```json theme={null} { "location": "Austin, TX", "status": "for_sale", "map_results_count": 842, "region": { "region_id": 10221, "region_type": 6 }, "map_bounds": { "north": 30.52, "east": -97.56, "south": 30.09, "west": -97.94 }, "pagination": { "current_page": 1, "per_page": 40, "total_pages": 20, "total_results": 842 }, "scraped_at": "2026-07-07T12:00:00Z", "results": [ { "position": 1, "zpid": "29499726", "detail_url": "https://www.zillow.com/homedetails/123-Main-St-Austin-TX-78701/29499726_zpid/", "home_type": "SINGLE_FAMILY", "home_status": "FOR_SALE", "status_text": "House for sale", "price": 460000, "price_raw": "$460,000", "currency": "USD", "zestimate": 468000, "rent_zestimate": 2600, "beds": 3, "baths": 2, "living_area": 1800, "lot_area_value": 6500, "lot_area_unit": "sqft", "address": "123 Main St, Austin, TX 78701", "city": "Austin", "state": "TX", "zipcode": "78701", "latitude": 30.2672, "longitude": -97.7431, "days_on_zillow": 4, "is_fsba": true, "img_src": "https://photos.zillowstatic.com/fp/abc-p_e.jpg" } ] } ``` Each search request costs **5 credits**. Failed requests are not charged. # Google AI Mode search Source: https://docs.scrapebadger.com/api-reference/google/google-ai-mode/google-ai-mode-search GET /v1/google/ai-mode/search Get AI-generated search results from Google AI Mode. ## Temporary unavailability If the service cannot obtain a complete AI Mode answer, it returns `503 Service Unavailable` instead of an empty answer or a misleading `404`. It does not substitute a regular search result or an AI Overview for an AI Mode answer. Wait at least the time specified by `Retry-After` before retrying (currently `5` seconds). Use bounded retries with backoff and reduce concurrency if failures continue. A retry is not guaranteed to succeed. Failed requests do not consume credits. See [credits and pricing](/credits-and-pricing). # Google search suggestions Source: https://docs.scrapebadger.com/api-reference/google/google-autocomplete/google-search-suggestions GET /v1/google/autocomplete Get Google search autocomplete suggestions. # Get stock/index quote Source: https://docs.scrapebadger.com/api-reference/google/google-finance/get-stockindex-quote GET /v1/google/finance/quote Get a stock or index quote from Google Finance. # Google Flights Booking Options Source: https://docs.scrapebadger.com/api-reference/google/google-flights/flights-booking-options GET /v1/google/flights/booking_options List the providers (airline and OTAs) that can book a selected itinerary, with per-provider prices. Pass a `selection_token` from a [Flights Search](/api-reference/google/google-flights/flights-search) offer — either a one-way offer, or a round-trip offer returned by the `departure_token` step (i.e. with both legs selected). Prices include mandatory taxes and fees for the whole party, same as search results. An incomplete round-trip selection (outbound only, no return chosen yet) returns an empty `booking_options` list — follow that offer's `departure_token` first. # Google Flights Search Source: https://docs.scrapebadger.com/api-reference/google/google-flights/flights-search GET /v1/google/flights/search Search Google Flights for one-way, round-trip, or multi-city itineraries with prices, emissions, and price insights. ## Prices `price` is the price exactly as Google Flights displays it: the **total for the entire party** (all passengers combined), **including mandatory taxes and fees**. Optional extras such as checked bags or seat selection are not included. `price_type` is always `total`. ## Full inventory: `sort_by=price` By default (`sort_by=top`) the endpoint returns Google's **"Top departing flights"** — the \~6-8 recommended picks, fast. That set demotes cheap-but-long- layover itineraries, so for price monitoring pass **`sort_by=price`** to get the **full price-sorted inventory**: every carrier and the cheap long-layover fares, cheapest first, plus a richer `price_insights` — Google's own `lowest_price`, `typical_price_range`, and `price_history`. `sort_by=price` runs a heavier render, so it is slower than the default and, if Google is slow to respond, falls back to the `top` set for that call. It applies to the round-trip / one-way initial search (not the `departure_token` return-leg step). A few extreme self-transfer fares Google labels "price unavailable" are included with a `null` `price`. ## Round trips: the two-step flow Google Flights selects a round trip in two steps — first the outbound, then the return — and this API mirrors that: 1. **Search** with `trip_type=round_trip`, `outbound_date`, and `return_date`. Each offer's `legs` contain the **outbound segments only**, and its `price` is the lowest complete round-trip total available with that outbound (Google pairs it with the cheapest compatible return). 2. **Pick the return**: call this endpoint again with the same parameters plus the chosen offer's `departure_token`. The response lists the return-leg options; each offer's `price` is the exact final round-trip total for that outbound + return pairing, and its `booking_url` opens the Google Flights booking page for the fully selected itinerary. Use its `selection_token` with [Booking Options](/api-reference/google/google-flights/flights-booking-options) to list per-provider prices. Each call is billed as a regular Flights search. For **one-way** searches the offer is already fully selected: `booking_url` opens the booking page directly and `departure_token` is `null`. # Hotel details Source: https://docs.scrapebadger.com/api-reference/google/google-hotels/hotel-details GET /v1/google/hotels/details Hotel details # Search hotels Source: https://docs.scrapebadger.com/api-reference/google/google-hotels/search-hotels GET /v1/google/hotels/search Search hotels # Search Google Images Source: https://docs.scrapebadger.com/api-reference/google/google-images/search-google-images GET /v1/google/images/search Search Google Images for visual content. # Search Google Jobs Source: https://docs.scrapebadger.com/api-reference/google/google-jobs/search-google-jobs GET /v1/google/jobs/search Search Google Jobs # Google Lens visual search Source: https://docs.scrapebadger.com/api-reference/google/google-lens/google-lens-visual-search GET /v1/google/lens/search Search Google Lens by image URL for visually similar results. # Local Pack Search Source: https://docs.scrapebadger.com/api-reference/google/google-local/local-pack-search GET /v1/google/local/search Return Google Local Pack business listings ranked for a SERP query with local intent. # Get business posts Source: https://docs.scrapebadger.com/api-reference/google/google-maps/get-business-posts GET /v1/google/maps/posts Get business posts # Get place details Source: https://docs.scrapebadger.com/api-reference/google/google-maps/get-place-details GET /v1/google/maps/place Get place details # Get place photos Source: https://docs.scrapebadger.com/api-reference/google/google-maps/get-place-photos GET /v1/google/maps/photos Get place photos # Get place reviews Source: https://docs.scrapebadger.com/api-reference/google/google-maps/get-place-reviews GET /v1/google/maps/reviews Get place reviews # Search Google Maps places Source: https://docs.scrapebadger.com/api-reference/google/google-maps/search-google-maps-places GET /v1/google/maps/search Search Google Maps places # News by topic Source: https://docs.scrapebadger.com/api-reference/google/google-news/news-by-topic GET /v1/google/news/topics News by topic # Search Google News Source: https://docs.scrapebadger.com/api-reference/google/google-news/search-google-news GET /v1/google/news/search Search Google News # Trending news Source: https://docs.scrapebadger.com/api-reference/google/google-news/trending-news GET /v1/google/news/trending Trending news # Patent details Source: https://docs.scrapebadger.com/api-reference/google/google-patents/patent-details GET /v1/google/patents/detail Patent details # Search patents Source: https://docs.scrapebadger.com/api-reference/google/google-patents/search-patents GET /v1/google/patents/search Search patents # Immersive product detail Source: https://docs.scrapebadger.com/api-reference/google/google-products/immersive-product-detail GET /v1/google/products/detail Get deep product details from Google's immersive product page. ## Identifying the product This endpoint does **not** take an arbitrary `product_id`. To look a product up you must supply its **`gpcid`** — Google's Shopping product identifier — together with the original search query `q` that surfaced it. Pass the `gpcid` value in the `product_id` parameter: ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google/products/detail?product_id=12337842083609640743&q=wireless+earbuds" \ -H "x-api-key: YOUR_API_KEY" ``` The `gpcid` is returned as the `gpcid` (also surfaced as `product_id`) field on every [`/v1/google/shopping/search`](/api-reference/google/google-shopping/search-products) result tile. The `q` is required because Google's RPC re-renders the SERP for that exact query to mint the session tokens used to fetch the detail page — so the product must be discoverable via `q`. **Prefer `page_token` for new integrations.** Each `/v1/google/shopping/search` tile also returns a bundled `page_token` that encodes the `gpcid`, `q`, `gl`, `hl`, and `domain` for you. Passing `page_token` alone takes precedence over the legacy `product_id` + `q` form, so you don't have to track the original query yourself. # Get Scholar Author Profile Source: https://docs.scrapebadger.com/api-reference/google/google-scholar/get-scholar-author GET /v1/google/scholar/author Get a full Google Scholar author profile including articles, citation stats, and co-authors. # Get Scholar Author Citation Chart Source: https://docs.scrapebadger.com/api-reference/google/google-scholar/get-scholar-author-citation GET /v1/google/scholar/author/citation Return the citations-per-year chart for a Google Scholar author. # Get Scholar Citation Formats Source: https://docs.scrapebadger.com/api-reference/google/google-scholar/get-scholar-cite GET /v1/google/scholar/cite Return MLA, APA, Chicago, Harvard, and Vancouver citation formats for a paper. # Search Google Scholar Source: https://docs.scrapebadger.com/api-reference/google/google-scholar/search-google-scholar GET /v1/google/scholar/search Search Google Scholar for scholarly articles. # Search Scholar Profiles Source: https://docs.scrapebadger.com/api-reference/google/google-scholar/search-scholar-profiles GET /v1/google/scholar/profiles Search Google Scholar for author profiles by name. # Google web search Source: https://docs.scrapebadger.com/api-reference/google/google-search/google-web-search GET /v1/google/search Search Google and get structured results (organic, ads, KG, AI overview, PAA). **The `num` parameter is deprecated.** Google no longer honours `num` to widen a page — a single request returns roughly **10 organic results per page**, regardless of the value you pass. To collect more results, paginate with the **`start`** offset (`start=0`, `10`, `20`, …) and merge the pages client-side. # Product details Source: https://docs.scrapebadger.com/api-reference/google/google-shopping/product-details GET /v1/google/shopping/product Product details # Resolve merchant URL for a product Source: https://docs.scrapebadger.com/api-reference/google/google-shopping/resolve-merchant-url-for-a-product GET /v1/google/shopping/product/click Resolve the direct merchant URL for a product from Google Shopping. # Search products Source: https://docs.scrapebadger.com/api-reference/google/google-shopping/search-products GET /v1/google/shopping/search Search products # Google Shorts Search Source: https://docs.scrapebadger.com/api-reference/google/google-shorts/shorts-search GET /v1/google/shorts/search Return short-form vertical video results from Google Shorts mode (YouTube Shorts, TikTok, etc.). # Interest over time Source: https://docs.scrapebadger.com/api-reference/google/google-trends/interest GET /v1/google/trends/interest Time-series interest data for up to 5 search terms (TIMESERIES widget). Stable response shape; direct shortcut to /trends/search?data_type=TIMESERIES. ## Time range (`date`) The `date` parameter only accepts Google Trends' own time-range formats — there is **no** arbitrary custom range outside the values Google itself supports. | `date` value | Range | | - | - | | `now 1-H` | Past hour | | `now 4-H` | Past 4 hours | | `now 1-d` | Past day | | `now 7-d` | Past 7 days | | `today 1-m` | Past 30 days | | `today 3-m` | Past 90 days | | `today 12-m` | Past 12 months | | `today 5-y` | Past 5 years | | `all` | 2004–present (default) | | `YYYY-MM-DD YYYY-MM-DD` | Explicit start/end dates (space-separated) | The explicit `YYYY-MM-DD YYYY-MM-DD` form must still fall within Google's accepted bounds (from 2004 to the present). Values outside these formats are rejected. # Interest by region Source: https://docs.scrapebadger.com/api-reference/google/google-trends/regions GET /v1/google/trends/regions Geographic interest breakdown for a search term (GEO_MAP widget). `resolution=auto` uses Google's hierarchy — COUNTRY worldwide, REGION inside a country, DMA inside the US. # Related topics & queries Source: https://docs.scrapebadger.com/api-reference/google/google-trends/related GET /v1/google/trends/related Returns both `related_topics` (Knowledge Graph entities with rising/top buckets) and `related_queries` (string queries with rising/top buckets) in a single response. # Search Source: https://docs.scrapebadger.com/api-reference/google/google-trends/search GET /v1/google/trends/search Unified Google Trends dispatcher — pick interest over time, compared breakdown, interest by region, related topics, or related queries via `data_type`. # Trends Topic Autocomplete Source: https://docs.scrapebadger.com/api-reference/google/google-trends/topic-autocomplete GET /v1/google/trends/autocomplete Resolve a query prefix into categorized Knowledge Graph topic entities. # Trending searches Source: https://docs.scrapebadger.com/api-reference/google/google-trends/trending GET /v1/google/trends/trending Trending searches with related queries from Google's TrendsUi batchexecute backend. Richer payload than the RSS feed surfaced by /trending-now. # Trending now Source: https://docs.scrapebadger.com/api-reference/google/google-trends/trending-now GET /v1/google/trends/trending-now Current trending searches with search_volume, increase_percentage, and related news articles. # Search Google Videos Source: https://docs.scrapebadger.com/api-reference/google/google-videos/search-google-videos GET /v1/google/videos/search Search Google for video results. # API Reference Source: https://docs.scrapebadger.com/api-reference/introduction Complete API reference for web scraping and Twitter data. 50+ endpoints for scraping any website and accessing Twitter data. ## Base URL ``` https://scrapebadger.com/v1 ``` All API endpoints are prefixed with this base URL. Authentication is required for all requests. ## Authentication Include your API key in the `x-api-key` header with every request: ```bash theme={null} curl -X POST "https://scrapebadger.com/v1/web/scrape" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://scrapebadger.com", "format": "markdown"}' ``` See the [Authentication guide](/authentication) for more details. ## Endpoint Categories ### Web Scraping | Category | Endpoints | Description | | - | - | - | | [Web Scraping](/api-reference/endpoint/web-scraping/scrape) | 2 | Scrape any website with anti-bot bypass, JS rendering, and AI extraction | ### Twitter | Category | Endpoints | Description | | - | - | - | | [Tweets](/api-reference/endpoint/tweets/get-tweet-detail) | 11 | Get tweet details, replies, retweets, likes, edit history, community notes, and search | | [Users](/api-reference/endpoint/users/get-user-by-username) | 11 | Fetch user profiles, followers, following, mentions, articles, and batch lookups | | [Lists](/api-reference/endpoint/lists/get-list-details) | 3 | Access Twitter lists, their tweets, and search within lists | | [Communities](/api-reference/endpoint/communities/get-community-details) | 3 | Explore communities, their members, and content | | [Trends](/api-reference/endpoint/trends/get-trending-topics) | 2 | Get trending topics globally or for specific locations | | [Geo](/api-reference/endpoint/geo/search-places) | 2 | Search and retrieve geographic place information | | [Spaces](/api-reference/endpoint/spaces/get-space-details) | 2 | Access Twitter Spaces and live broadcasts | ## Common Patterns ### Pagination Most list endpoints support cursor-based pagination. The response includes a `next_cursor` field that you can pass to the `cursor` parameter to fetch the next page. ```bash theme={null} # First request curl "https://scrapebadger.com/v1/twitter/users/elonmusk/followers" \ -H "x-api-key: YOUR_API_KEY" # Response includes next_cursor # { "data": [...], "next_cursor": "abc123" } # Next page curl "https://scrapebadger.com/v1/twitter/users/elonmusk/followers?cursor=abc123" \ -H "x-api-key: YOUR_API_KEY" ``` ### Error Handling All errors return a JSON object with a `detail` field: ```json theme={null} { "detail": "User not found" } ``` ### Credits All endpoints cost **1 credit per request**. Failed requests (4xx/5xx) do not consume credits. See [Credits & Pricing](/credits-and-pricing) for details. *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by X. "X" and "Twitter" are trademarks of X Corp., used here only to describe the platform this scraper is designed to work with.* # App Store Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/app-store/overview Search the App Store, pull full app detail with the star histogram, in-app-purchase list and App Privacy label, read customer reviews, browse a developer's catalogue and the top charts — across 170 storefronts. ## Scraper API for the Apple App Store The ScrapeBadger **App Store API** returns Apple's app catalogue as JSON: full app detail (bundle id, version, pricing, ratings, genres, minimum OS, file size, screenshots, in-app purchases and what's new), full-text search, per-storefront customer reviews, a developer's catalogue and the top-free / top-paid / top-grossing charts. All endpoints are `GET`, live under `https://scrapebadger.com/v1/app-store/*`, and authenticate with the `X-API-Key` header. Credits are charged per request (see the table below) and reported on the `X-Credits-Used` response header. ## Features * **Two ids, one route** — `/apps/{app_id}` accepts either the numeric track id (`310633997`) or the bundle id (`com.whatsapp`). A value containing a dot is treated as a bundle id. * **Rich detail** — around 40 core fields per app: `bundle_id`, `version`, `price`/`formatted_price`, `rating` and `rating_count` (plus current-version ratings), `genres` and `genre_ids`, `minimum_os_version`, `file_size_bytes`, `content_rating`, `advisories`, `language_codes`, `supported_devices` and every artwork URL. * **`extras` enrichment** — the storefront page adds what the API omits: the 1–5 star `rating_histogram`, the `in_app_purchases` price list, full-resolution iPhone and iPad screenshots with dimensions, `whats_new`, chart position, Editors' Choice and the App Privacy ("nutrition label") breakdown. * **Reviews** — 50 per page, pages 1–10, `mostRecent` or `mostHelpful`, with Apple's helpful-vote counts. * **Charts** — top-free, top-paid and top-grossing for iPhone or iPad, optionally scoped to a genre. * **Dual timestamps** — every date ships twice: `*_utc` (Unix seconds) and `*_at` (ISO 8601 UTC). ## Storefronts and catalogues `country` is Apple's storefront code (lowercase ISO 3166-1 alpha-2, e.g. `us`, `de`, `jp`) and governs pricing, availability, review sets and charts. [`GET /v1/app-store/markets`](/api-reference/endpoint/app-store/list-markets) (free) lists 170 storefronts; any well-formed 2-letter code is accepted and Apple arbitrates. `entity` on `/search` picks the **catalogue**, and the catalogues are separate rather than filters — `software` (iPhone), `iPadSoftware` and `macSoftware`. A Mac-only app is absent from `software` entirely. ## Credits | Endpoint | Path | Credits | | - | - | - | | Search apps | `GET /v1/app-store/search` | 5 | | App detail | `GET /v1/app-store/apps/{app_id}` | 5 | | App reviews | `GET /v1/app-store/apps/{app_id}/reviews` | 5 | | Developer apps | `GET /v1/app-store/developers/{developer_id}` | 5 | | Top charts | `GET /v1/app-store/charts` | 5 | | List genres | `GET /v1/app-store/genres` | 0 | | List markets | `GET /v1/app-store/markets` | 0 | ## Quickstart ```bash cURL theme={null} curl "https://scrapebadger.com/v1/app-store/apps/310633997?country=us" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/app-store/apps/310633997?country=us", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const app = await res.json(); console.log(app.name, app.version, app.rating, app.extras?.rating_histogram); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/app-store/apps/310633997", headers={"X-API-Key": "YOUR_API_KEY"}, params={"country": "us"}, ) app = res.json() print(app["name"], app["version"], app["rating"]) ``` ## Result depth **Search is capped at 200 results per query, with no deep paging.** Apple's Search API rejects its own `offset` parameter, so `offset` here is a slice of one 200-result response and `offset + limit` is capped at 200. * **Reviews** stop at page 10 (500 reviews per storefront per sort). Apple hard-rejects page 11+, so the ceiling is enforced with a clear `400` rather than a confusing upstream error. * **Charts** return up to 200 entries; `rank` is the app's position in the feed. ## Other notes * **Reviews are per-storefront**, not translations: the `us` and `de` feeds for one app are different review sets. * **Reviews need a numeric id.** Apple's review feed has no bundle-id form — resolve a bundle id through `/apps/{bundle_id}` first and use its `app_id`. * **`extras` is best-effort.** It comes from Apple's server-rendered product page, a web-client implementation detail; if that fetch or parse fails the response degrades to the core iTunes fields rather than failing. Set `include_extras=false` to skip the second fetch entirely. ## Errors | Status | Meaning | | - | - | | `400` | Bad country, entity, sort, chart type or genre id; a bundle id where a numeric id is required; review page above 10. | | `404` | No such app, or no such developer in that storefront. | | `429` | Apple is throttling — retry shortly. | | `502` | Unexpected upstream failure — **not billed**. | Search results carry the same \~40 fields as the detail endpoint, so a search hit rarely needs a follow-up lookup unless you want `extras`. *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Apple. "Apple" and "App Store" are trademarks of Apple Inc., used here only to describe the platform this scraper is designed to work with.* # Authentication Source: https://docs.scrapebadger.com/authentication Learn how to authenticate with the ScrapeBadger API using API keys. All API requests require authentication using an API key. Learn how to create and manage your keys securely. ## Getting an API Key [Sign in](https://scrapebadger.com/auth/signin) to your ScrapeBadger account. Your first API key is created automatically and shown on the [dashboard](https://scrapebadger.com/dashboard), where you can copy or regenerate it anytime. Open the [API Keys](https://scrapebadger.com/dashboard/api-keys) page and click **Create key**. Give it a name, optional notes, the APIs it may call and an optional expiry date. Copy the key and store it as a secret (for example in an environment variable). ## Using Your API Key Include your API key in every request using one of these methods: ### Header Authentication (Recommended) Pass your API key in the `x-api-key` header. This is the recommended method as it keeps your key out of URLs and logs. ```bash theme={null} curl -X GET "https://scrapebadger.com/v1/twitter/users/elonmusk/by_username" \ -H "x-api-key: sb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ``` ### Query Parameter Alternatively, pass your API key as a query parameter. Note that this method may expose your key in logs and browser history. ```bash theme={null} curl -X GET "https://scrapebadger.com/v1/twitter/users/elonmusk/by_username?api_key=sb_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ``` ## Error Responses If authentication fails, the API returns one of these status codes: | Status | Name | Description | | - | - | - | | `401` | Unauthorized | Missing, invalid, disabled or expired API key. Check that you're including the key correctly. | | `402` | Payment Required | Insufficient credits. Purchase more credits to continue making requests. | | `403` | Forbidden | The key is not permitted to call this API (`insufficient_scope`), the request came from an IP address the key doesn't allow (`ip_not_allowed`), or the account is restricted. See below. | ```json Error Response Format theme={null} { "detail": "Invalid or expired API key." } ``` ## API Key Permissions Every key either has access to **all APIs** (the default, including APIs added in the future) or is **restricted** to the APIs you pick — for example a key that may only call Google and Amazon. Set this when you create the key or later with **Edit** on the [API Keys](https://scrapebadger.com/dashboard/api-keys) page; changes apply to the key's very next request. Permissions are per API, matching the first path segment after `/v1/`: `twitter`, `google`, `amazon`, `web`, `youtube`, and so on. Everything under that API — including Twitter stream monitors, filter rules and the stream WebSocket — is covered by its permission. `/v1/account` is always allowed. A request to an API the key isn't permitted to call is rejected **before** any credits are charged, with `403` and `error: "insufficient_scope"`: ```json 403 insufficient_scope theme={null} { "detail": "This API key does not have permission to use the Twitter / X API (/v1/twitter). It is restricted to: Google, Amazon. Grant the Twitter / X permission to this key at https://scrapebadger.com/dashboard/api-keys, or use a different key.", "error": "insufficient_scope", "required_scope": "twitter", "allowed_scopes": ["google", "amazon"] } ``` The official SDKs raise `PermissionDeniedError` for this response, with `required_scope` and `allowed_scopes` attached. Give each application its own key restricted to the APIs it uses. A leaked key then exposes only those APIs, and you can revoke it without touching anything else. ## IP Restrictions Limit a key to the IP addresses your servers use, so a leaked key is useless anywhere else. On the [API Keys](https://scrapebadger.com/dashboard/api-keys) page, open **Edit → IP restrictions**, choose **Only these addresses** and add: * single addresses: `203.0.113.7`, `2001:db8::1` * CIDR ranges: `203.0.113.0/24`, `2001:db8::/48` **Add my current IP** fills in the address of the browser you're using — your servers may use a different one. Up to 100 entries per key; IPv4 and IPv6 are both supported. Changes apply on the key's next request. A request from any other address is rejected **before** any credits are charged, with `403` and `error: "ip_not_allowed"`. The response names the address we saw, so you can tell a misconfigured server from someone else using your key: ```json 403 ip_not_allowed theme={null} { "detail": "This API key only accepts requests from specific IP addresses, and this request came from 198.51.100.23, which is not on its allowlist. If this is your server, add 198.51.100.23 (or its range) to the key at https://scrapebadger.com/dashboard/api-keys. If not, someone else may be using your key: rotate it.", "error": "ip_not_allowed", "client_ip": "198.51.100.23" } ``` The official SDKs (0.53.0+) raise `IPNotAllowedError`, a subclass of `PermissionDeniedError`, with `client_ip`. The address is taken from the network connection as it reaches Cloudflare — it can't be set with headers such as `X-Forwarded-For`. Keys with IP restrictions don't work through the hosted [MCP server](/mcp/overview): its requests come from your AI assistant's provider, not your servers. Use a separate, unrestricted key there. ## Security Best Practices API keys should only be used in server-side code. Never include them in frontend JavaScript, mobile apps, or public repositories. Create separate API keys for development, staging, and production. This makes it easier to rotate keys and track usage. Periodically create new API keys and deactivate old ones. If a key is compromised, you can disable it without affecting other keys. ## Managing API Keys From the [API Keys](https://scrapebadger.com/dashboard/api-keys) page you can: * Create multiple API keys for different projects and environments * Add notes describing what uses each key * Restrict each key to specific APIs, or allow all APIs * Limit each key to specific IP addresses or CIDR ranges * Set an expiry date after which the key stops working * Rename keys and enable or disable them without deleting them * View and copy a key again later, and see usage per key * Delete keys that are no longer needed Working with colleagues? [Teams](/teams) let several accounts share one balance, with member keys and service keys managed by team admins. # Baidu Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/baidu/overview Scrape Baidu — China's #1 search engine — as clean JSON: web SERP with language and date-window filters, the news vertical, image search and autocomplete. Every result carries the real target URL, not Baidu's tracking redirect. No China proxy required. ## Scraper API for Baidu The ScrapeBadger **Baidu API** turns `baidu.com` into a clean JSON feed: the web SERP (with language and publish-date filters), the news vertical, image search with full-size image URLs and pixel dimensions, and search-box autocomplete. Baidu is **China's #1 search engine at roughly 60% market share** — the single largest search surface outside Google, and the one that decides visibility for the Chinese-language web. It is also the search engine most Western SEO and market-research tooling simply skips. All endpoints are `GET`, live under `https://scrapebadger.com/v1/baidu/*`, and authenticate with the `X-API-Key` header. Credits are charged per request (see the table below) and reported on the `X-Credits-Used` response header. ## The real URL, not the redirect Baidu does not link straight to a result. Every organic link is a `baidu.com/link?url=...` tracking redirect that only resolves to the destination when followed — which is why competing Baidu APIs hand you a `baidu.com` URL and leave you to make one extra HTTP request per result to learn where it actually goes. ScrapeBadger returns **both**, on every result: | Field | What it is | | - | - | | `url` | The **real target URL**, decoded from the result's `mu` attribute. | | `baidu_url` | Baidu's `baidu.com/link?url=` tracking redirect. | ```json theme={null} { "position": 1, "title": "专业咖啡机价格 - 阿里巴巴", "url": "https://www.1688.com/jiage/-D7A8D2B5BFA7B7C8BBFA.html", "baidu_url": "http://www.baidu.com/link?url=m4_ZyR-m51ZWH--9M5Fnrzn4W0Nebua" } ``` So a rank-tracking or domain-visibility job needs **one call, not 1 + N** — you can group results by real hostname straight out of the response. ## Global access, no China proxy Baidu is reachable from outside China but rate-limits and challenges foreign traffic aggressively. ScrapeBadger absorbs that: requests are served through its own exit pool with session reuse and challenge handling, so **you do not need a China-based proxy, a mainland VPS, or an ICP filing**. Call the API from anywhere. ## Features * **Web search** — organic results with `title`, real `url`, `snippet`, `source` (the site name Baidu shows), `date`/`date_at`, `thumbnail` and Baidu's own `tpl` template id. Up to **50 results per page**. * **Language filter** — restrict to simplified (`zh-cn`) or traditional (`zh-tw`) Chinese, or leave it open with `all`. * **Publish-date window** — `time_from` / `time_to` as Unix timestamps, mapped onto Baidu's own `gpc` date filter. * **Related searches** — Baidu's query suggestions from the foot of the SERP, with their SERP URLs, for keyword expansion. * **News vertical** — articles with publisher, publish date and real article URLs, ordered by relevance or recency. * **Image search** — full-size `image_url` (Baidu's decoded `objURL`), three Baidu-hosted copies (`thumbnail_url`, `middle_url`, `hover_url`), pixel `width`/`height`, format, and the source page (`from_url`, `from_title`). * **Autocomplete** — Baidu's search-box suggestions for 1 credit, the cheapest way to expand a seed term into real Chinese queries. ## Dates Every dated result ships **two** fields: | Field | Value | | - | - | | `date` | Baidu's own string, exactly as rendered — `2026年8月1日`, `3天前`, `2小时前`. | | `date_at` | ISO 8601 date (`YYYY-MM-DD`), set **only** when the raw form is unambiguous. | There is deliberately **no timestamp field**. Baidu's SERP carries no time-of-day, so a midnight epoch would be fabricated precision. Sort on `date_at` and keep `date` for display. ## Credits | Endpoint | Path | Credits | | - | - | - | | Web search | `GET /v1/baidu/search` | 5 | | News | `GET /v1/baidu/news` | 5 | | Images | `GET /v1/baidu/images` | 5 | | Autocomplete | `GET /v1/baidu/autocomplete` | 1 | ## Quickstart ```bash cURL theme={null} curl "https://scrapebadger.com/v1/baidu/search?query=%E5%92%96%E5%95%A1%E6%9C%BA&num=20" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} import { ScrapeBadger } from "scrapebadger"; const client = new ScrapeBadger({ apiKey: process.env.SCRAPEBADGER_API_KEY }); const results = await client.baidu.search("咖啡机", { num: 20, language: "zh-cn" }); for (const r of results.results) { // r.url is the real destination, r.baidu_url the tracking redirect console.log(`${r.position}. ${r.title} — ${r.url}`); } ``` ```python Python theme={null} import asyncio from scrapebadger import ScrapeBadger async def main(): async with ScrapeBadger(api_key="YOUR_API_KEY") as client: results = await client.baidu.search("咖啡机", num=20, language="zh-cn") for r in results.results: print(r.position, r.title, r.url) asyncio.run(main()) ``` ## Pagination limits `total_results` is **Baidu's own claim** (parsed from `百度为您找到相关结果约N个`), not a reachable count. Baidu's SERP stops serving results past roughly **page 76** regardless of the total it reports, so `page` is clamped to `1`–`76` — a request beyond the wall is rejected rather than billed for a structurally empty page. * `num` controls page size, `1`–`50` (Baidu's own cap). Fewer, bigger pages is the cheaper way to depth: `num=50` reaches 500 results in 10 calls. * Page offset is `(page - 1) * num`, so **changing `num` between pages shifts the window.** Keep `num` fixed for the whole crawl of one query. * Images are a fixed **30 per page**, `page` `1`–`50`. To go wider than one query's page wall, expand the seed instead of paging deeper: run [`/autocomplete`](/api-reference/endpoint/baidu/autocomplete) (1 credit) and the `related_searches` off the first SERP, then search each term and merge on `url`. Cheaper coverage than paging to 76. ## Character encoding Queries are Chinese in practice, so **URL-encode the query as UTF-8** and let your HTTP client do it (`URLSearchParams`, `requests` `params=`, the SDKs). Every response is UTF-8; `snippet` and `title` come back with Baidu's own punctuation (`,`, `、`) intact rather than transliterated. Latin queries work too — Baidu serves a mixed SERP for `coffee machine` — but Chinese terms return meaningfully richer results. ## Errors | Status | Meaning | | - | - | | `422` | Anti-bot challenge — **not billed**. Retry; it succeeds. | | `502` | Baidu returned a page without the expected result container. Retry. | Baidu serves a challenge page with HTTP 200. Those are detected by result- container marker, not status code, and surfaced as `422` so a challenge is never billed or mistaken for a genuinely empty SERP. *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Baidu. "Baidu" is a trademark of Baidu, Inc., used here only to describe the platform this scraper is designed to work with.* # Bing Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/bing/overview Search Bing's web SERP with organic results, ads and related searches, plus image, video and news search and query autocomplete — across 30+ markets, no Bing API key required. ## Scraper API for Bing The ScrapeBadger **Bing API** turns `bing.com` into a clean JSON feed: the web SERP (organic results with resolved destination URLs, ads, related searches and the true reported match count), image search with full-size URLs and dimensions, video search with duration and publisher, news search with absolute publish timestamps, and search-box autocomplete. All endpoints are `GET`, live under `https://scrapebadger.com/v1/bing/*`, and authenticate with the `X-API-Key` header. Credits are charged per request (see the table below) and reported on the `X-Credits-Used` response header. ## Features * **Web SERP** — organic results with `position`, resolved destination `url` (Bing's `/ck/a` redirects are decoded), `display_url`, `site_name`, `snippet` and `deep_links[]`, plus `ads[]`, `related_searches[]` and Bing's reported `total_results`. * **Image search** — full-size `image_url`, `thumbnail_url`, the page the image lives on (`source_url` / `source_domain`) and pixel `width`/`height`. * **Video search** — title, thumbnail, `duration`, host platform (`source`, e.g. YouTube), `publisher`, `views` and age. * **News search** — headline, publisher, snippet and **absolute publish times** (`published_at` ISO 8601 plus `published_utc` Unix), with a `freshness` filter of `day`, `week` or `month`. * **Autocomplete** — Bing's search-box suggestions for 1 credit. * **SafeSearch control** — `safe_search=off|moderate|strict` on search, images and videos. ## Markets Every endpoint takes a single `market` code in `language-COUNTRY` form (`en-US`, `de-DE`, `pt-BR`, …). There are no per-country domains — every market is served from `www.bing.com`; the market sets the result language and country ranking, and requests exit from an IP in the matching country. [`GET /v1/bing/markets`](/api-reference/endpoint/bing/list-markets) (free) returns the curated reference set of 30 market codes. Any well-formed `mkt` value is accepted by the search endpoints, including ones not on that list. ## Credits | Endpoint | Path | Credits | | - | - | - | | Web search | `GET /v1/bing/search` | 5 | | Image search | `GET /v1/bing/images` | 5 | | Video search | `GET /v1/bing/videos` | 5 | | News search | `GET /v1/bing/news` | 5 | | Autocomplete | `GET /v1/bing/autocomplete` | 1 | | List markets | `GET /v1/bing/markets` | 0 | ## Quickstart ```bash cURL theme={null} curl "https://scrapebadger.com/v1/bing/search?query=coffee+machine&market=en-GB" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/bing/search?" + new URLSearchParams({ query: "coffee machine", market: "en-GB", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); console.log(data.total_results, "matches,", data.result_count, "returned"); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/bing/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "coffee machine", "market": "en-GB"}, ) data = res.json() print(data["total_results"], "matches,", data["result_count"], "returned") ``` ## Result depth `/search` has a **depth ceiling**. Bing serves non-JS clients a server-rendered layout that carries the first **\~4–10 organic results** and lazy-loads the rest only in a real JS browser. The API extracts everything Bing renders plus the true `total_results` count — it does not pretend to paginate past what Bing serves. `count` is an upper bound, not a guarantee. `/images` and `/videos` do not have this ceiling — their grids are server-rendered densely, so the default `count=35` is genuinely reachable. ## Other notes * **News comes from Bing's RSS feed**, not the HTML news cards. That is why publish times are absolute (`published_at`, `published_utc`) and the schema is stable — but article thumbnails are not included. * **Organic `url` values are final destinations.** Bing wraps every result in a `/ck/a` tracking redirect; the API resolves it so you get the real URL. * **`ads[]` and `related_searches[]`** appear only when Bing serves them for that query and market. ## Errors | Status | Meaning | | - | - | | `422` | Bing served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | Start from [`/autocomplete`](/api-reference/endpoint/bing/autocomplete) (1 credit) to expand a seed term into real Bing queries, then run [`/search`](/api-reference/endpoint/bing/search) on each suggestion. *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Microsoft. "Bing" is a trademark of Microsoft Corporation, used here only to describe the platform this scraper is designed to work with.* # Booking.com Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/booking/overview Scrape Booking.com hotel search with filters and sorting, destination autocomplete, full property detail, complete room rate tables, and paginated guest reviews — worldwide, with structured JSON responses. ## Scraper API for Booking.com Search hotels, apartments and every other stay type Booking.com sells, resolve free-text destinations to exact ids, pull a property's full detail — facilities, rooms, house rules, score breakdown, photos and guest Q\&A — pull its complete rate table for any dates, and page through guest reviews with language and guest-type filters. ScrapeBadger handles sessions and parsing automatically — no Booking.com account or API key required. ## Key Features Free-text [`location`](/api-reference/endpoint/booking/search) or an exact `dest_id`, with dates, occupancy, sorting and Booking's own filter ids. Resolve a prefix like `amsterd` to cities, districts, airports, landmarks and regions — each with an id you can pass straight to search. Description, address, GPS, star rating, score breakdown by category, 60-110 facilities, room types with beds and photos, house rules and guest Q\&A. Every rate on every room type for your dates — 30+ rates across 5 room types in one call, with per-room facilities, alternative bed layouts and meal plans. Positive and negative text, per-review score, stay dates, guest type, room stayed in, partner reply and photos. Every price comes back as both Booking's localized display string and a numeric `amount` + `currency`, so you never parse `"€ 265,09"`. First-class support via the ScrapeBadger Node.js and Python SDKs. Coverage is global — every country Booking.com sells in is reachable. Every endpoint accepts `currency` and `language`, defaulting to `USD` and `en-us`, so you can request prices and text in the market's own currency and language without changing anything else. `language` also localizes review-score words, room type names and price formatting. ## Coverage & Defaults | Parameter | Default | Notes | | - | - | - | | `currency` | `USD` | Any Booking-supported currency, e.g. `EUR`, `GBP`, `JPY`. | | `language` | `en-us` | Any Booking locale, e.g. `fr`, `de`, `es`, `it`. | | Room sizes | Follows `language` | [`/rooms`](/api-reference/endpoint/booking/get-rooms) reports `area_unit` as `SQUARE_METER` or `SQUARE_FEET` depending on the requested locale. | | Geography | Worldwide | Free-text `location` is geocoded by Booking; an exact `dest_id` + `dest_type` pair is also accepted. | Resolve a destination once with [`/destinations`](/api-reference/endpoint/booking/search-destinations), then pass its `dest_id` + `dest_type` to [`/search`](/api-reference/endpoint/booking/search) for an exact area instead of free-text geocoding. Every search result carries `country_code` and `slug` — the two path segments for [`/properties/{country_code}/{slug}`](/api-reference/endpoint/booking/get-property), [`/rooms`](/api-reference/endpoint/booking/get-rooms) and [`/reviews`](/api-reference/endpoint/booking/get-reviews). ## Quick Start ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/booking/search?" + new URLSearchParams({ location: "Rome, Italy", checkin: "2026-09-12", checkout: "2026-09-15", adults: "2", filters: "class=5;mealplan=1", currency: "EUR", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); console.log(data.total_results, "properties"); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/booking/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "location": "Rome, Italy", "checkin": "2026-09-12", "checkout": "2026-09-15", "adults": 2, "filters": "class=5;mealplan=1", "currency": "EUR", }, ) data = res.json() print(data["total_results"], "properties") ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/booking/search?location=Rome%2C%20Italy&checkin=2026-09-12&checkout=2026-09-15&adults=2&filters=class%3D5%3Bmealplan%3D1¤cy=EUR" \ -H "X-API-Key: YOUR_API_KEY" ``` ## Endpoints | Endpoint | Method | Description | | - | - | - | | [`/v1/booking/search`](/api-reference/endpoint/booking/search) | GET | Search properties by destination, with filters and sorting | | [`/v1/booking/destinations`](/api-reference/endpoint/booking/search-destinations) | GET | Resolve free text to Booking destination ids | | [`/v1/booking/properties/{country_code}/{slug}`](/api-reference/endpoint/booking/get-property) | GET | Full detail for a single property | | [`/v1/booking/properties/{country_code}/{slug}/rooms`](/api-reference/endpoint/booking/get-rooms) | GET | Every room type with its full rate table for given dates | | [`/v1/booking/properties/{country_code}/{slug}/reviews`](/api-reference/endpoint/booking/get-reviews) | GET | Paginated guest reviews | ## Credit Costs | Endpoint | Cost | | - | - | | Search properties | 5 credits | | Search destinations | 3 credits | | Get property detail | 5 credits | | Get rooms & rates | 10 credits | | Get reviews | 10 credits | | Health check | 0 credits | | Failed requests | 0 credits | ## Authentication All requests require your API key in the `X-API-Key` header: ```bash theme={null} curl "https://scrapebadger.com/v1/booking/search?location=Rome%2C%20Italy" \ -H "X-API-Key: YOUR_API_KEY" ``` Credits are charged per request (see the table above) and reported on the `X-Credits-Used` response header. ## Next Steps Full API reference for searching Booking.com stays Retrieve a property's complete detail by country code and slug *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Booking.com. "Booking.com" is a trademark of Booking.com B.V., used here only to describe the platform this scraper is designed to work with.* # ChatGPT API Overview Source: https://docs.scrapebadger.com/chatgpt/overview Ask the real chatgpt.com a question and get the answer back as structured JSON — with the web sources it cited, anchored to the exact text they support. No OpenAI account or API key required. ## Overview The ScrapeBadger **ChatGPT API** sends a prompt to **the real `chatgpt.com`** — not the OpenAI API — and returns the answer as structured JSON, including the web sources ChatGPT actually browsed and cited. Requests are **anonymous**: no OpenAI account, no OpenAI API key, no billing relationship with OpenAI. You see what a logged-out user in your chosen country sees. All endpoints live under `https://scrapebadger.com/v1/chatgpt/*` and authenticate with the `X-API-Key` header. `/ask` and `/brand-visibility` accept both `GET` (query params) and `POST` (JSON body). Credits are charged per request and reported on the `X-Credits-Used` response header. **Answers take 20-25s ungrounded, 30-70s with web search.** This is a live browse of chatgpt.com, not a cached lookup — the clock includes ChatGPT composing the answer and, when it browses, running its own web search. Set your HTTP client timeout to **60 s or more**; the default 5–10 s timeout in most SDKs will abort the call. ## Features * **Real ChatGPT answers** — the full text as rendered on chatgpt.com, plus a Markdown variant when one is available. * **Anchored citations** — every citation carries `start_index` / `end_index` character offsets into `answer` and the `matched_text` it supports, so you can highlight exactly which sentence a source backs. * **The full search trail** — `search_results` is everything ChatGPT retrieved, each flagged `cited: true/false`. `citations` is the subset it actually referenced. Most APIs only give you the second list. * **Did it really browse?** — `web_search_triggered` tells you whether ChatGPT ran a web search or answered from its own weights. Force it with `web_search=force`, or suppress it with `web_search=off`. * **Brand visibility (AEO/GEO) built in** — one call returns mention counts, position score, share of voice against named competitors, and whether your domain was cited. No separate subscription. * **Country control** — `country` picks the egress country, so you can compare the answer a user in `DE` gets against the one in `US`. * **Ask about an image** — attach a picture with `image_url` or `image_base64` and ChatGPT answers about it (JPEG/PNG/GIF/WEBP/BMP, up to 5 MB). Image *generation* is not available: anonymous chatgpt.com gates that behind a login. ## Honesty caveat Each request is a **single, fresh, anonymous question**. There is no conversation memory, no multi-turn follow-up, no model selection, no streaming, and no image OUTPUT — `conversation_id` and `message_id` identify the one-shot exchange, they are not handles you can continue from. The `model` field reports which model answered; it is **not** a request parameter, and `/models` is a read-only catalogue of what chatgpt.com currently offers. ChatGPT is non-deterministic: the same prompt asked twice can produce different wording and different sources. For monitoring use cases, sample repeatedly and aggregate rather than trusting a single call. ## Credits | Endpoint | Path | Credits | | - | - | - | | Ask | `GET`/`POST` `/v1/chatgpt/ask` | 20 | | Brand visibility | `GET`/`POST` `/v1/chatgpt/brand-visibility` | 25 | | List models | `GET /v1/chatgpt/models` | 1 | | Health | `GET`/`HEAD` `/v1/chatgpt/health` | 0 | At the PAYG rate of $0.15 per 1K credits, an `/ask` call is **$0.003\*\* — **\$3.00 per 1,000 answers**. Subscription tiers cut that substantially. Non-2xx responses are never billed. ## Quickstart ```bash cURL theme={null} curl "https://scrapebadger.com/v1/chatgpt/ask?prompt=What%20are%20the%20best%20web%20scraping%20APIs%20in%202026%3F" \ -H "X-API-Key: YOUR_API_KEY" \ --max-time 60 ``` ```javascript Node.js theme={null} const res = await fetch("https://scrapebadger.com/v1/chatgpt/ask", { method: "POST", headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ prompt: "What are the best web scraping APIs in 2026?", country: "US", web_search: "force", }), signal: AbortSignal.timeout(60_000), }); const data = await res.json(); console.log(data.answer); console.log(data.source_domains); ``` ```python Python theme={null} import requests res = requests.post( "https://scrapebadger.com/v1/chatgpt/ask", headers={"X-API-Key": "YOUR_API_KEY"}, json={ "prompt": "What are the best web scraping APIs in 2026?", "country": "US", "web_search": "force", }, timeout=60, ) data = res.json() print(data["answer"]) print(data["source_domains"]) ``` ## What you can build Track whether ChatGPT names your brand for the prompts your buyers ask, how early it names you, and how you rank against competitors — with [`/brand-visibility`](/api-reference/endpoint/chatgpt/brand-visibility). Find which domains ChatGPT trusts for a topic. `search_results` shows everything it retrieved; `cited` shows what survived into the answer. Compare answers across countries, or with `web_search` forced on and off, to separate what ChatGPT knows from what it looked up. Use `start_index` / `end_index` to attach a real source to each claim before republishing anything ChatGPT wrote. ## How we compare | Vendor | Price / 1K | Citations | Full search trail | Brand analysis | | - | - | - | - | - | | Bright Data | \$1.50 | Yes | No | No | | Apify `chatgpt-search` | \$3.00 | Yes | No | No | | DataForSEO LLM Scraper | \$1.20–4.00 | Yes | Yes | Separate product | | Scrapingdog | \~30 credits/req | **No** | No | No | | ScrapingBee | Credits | **No** | No | No | | **ScrapeBadger** | **\$3.00** (20 cr) | **Yes + text offsets** | **Yes** | **Bundled** | Five things that are genuinely ours: 1. **Citations anchored to the answer.** `start_index` / `end_index` / `matched_text` tell you *which sentence* a source supports. No other vendor returns text offsets. 2. **`web_search_triggered`.** Only Bright Data otherwise tells you whether ChatGPT really browsed — everyone else leaves you guessing whether a citation-free answer came from memory or a failed search. 3. **`search_results` vs `citations`.** The retrieved set *and* the referenced subset. Only DataForSEO separates these. 4. **Brand visibility in the same API.** Profound, Otterly, Peec and AthenaHQ sell this as a \$99–989/month subscription. Here it is a 25-credit call. 5. **Published typically under 30s ungrounded live latency.** DataForSEO's live tier quotes a 90 s SLA. ## FAQ No. This drives the public `chatgpt.com` web interface as an anonymous visitor. You do not need an OpenAI account, an OpenAI API key, or an OpenAI subscription — and answers include web citations, which the OpenAI completions API does not return. Because a real answer is being generated, and when ChatGPT browses it runs its own web search first. Budget a 60 s client timeout and run calls concurrently rather than in a tight sequence. No. Every request is a fresh, standalone question with no memory of previous calls. Put all necessary context in the single `prompt` (up to 4,096 characters). No. `/models` lists the model slugs chatgpt.com currently exposes, and the `model` field in a response reports which one answered — but you cannot request a specific one. Check `web_search_triggered`. If it is `false`, ChatGPT answered from its training data and there were no sources to cite — that is normal for general-knowledge prompts. Set `web_search=force` if you always want it to browse. No. ChatGPT is non-deterministic, and the live web changes. For tracking, sample the same prompt on a schedule and look at the trend, not a single result. It changes the egress country of the request, which affects the localised results ChatGPT retrieves and can change the answer's emphasis and language. Pass any ISO-3166 alpha-2 code; the default is `US`. You get `{"detail": {"code": ..., "message": ...}}` with an HTTP status of 422, 429 or 502 depending on the cause. **Non-2xx responses are never billed**, so a retry costs you nothing extra beyond the successful call. Start with [`/ask`](/api-reference/endpoint/chatgpt/ask) to see the shape of a real answer, then move to [`/brand-visibility`](/api-reference/endpoint/chatgpt/brand-visibility) once you know which prompts matter for your market. # Command Reference Source: https://docs.scrapebadger.com/cli/commands Full reference for all ScrapeBadger CLI commands. # Command Reference ## Account Commands ### `scrapebadger auth` Set up or view your API key. ```bash theme={null} scrapebadger auth --api-key sb_live_... # Set key directly scrapebadger auth # Interactive prompt scrapebadger auth --show # Show saved key ``` ### `scrapebadger credits` Check your credit balance. ### `scrapebadger logout` Remove saved API key from config. --- ## Twitter Commands All Twitter commands are under `scrapebadger twitter`. ### Users ```bash theme={null} scrapebadger twitter user # Profile by username scrapebadger twitter user-id # Profile by numeric ID scrapebadger twitter followers # Followers list scrapebadger twitter following # Following list scrapebadger twitter mentions # Tweets mentioning user ``` ### Tweets ```bash theme={null} scrapebadger twitter tweet # Single tweet scrapebadger twitter tweets # User's latest tweets scrapebadger twitter search # Advanced search scrapebadger twitter replies # Tweet replies scrapebadger twitter quotes # Quote tweets scrapebadger twitter retweeters # Who retweeted ``` ### Discovery ```bash theme={null} scrapebadger twitter trends # Global trends scrapebadger twitter trends --place # Location trends scrapebadger twitter community # Community details scrapebadger twitter community-tweets # Community tweets scrapebadger twitter search-communities # Search communities scrapebadger twitter list # List details scrapebadger twitter list-tweets # List tweets scrapebadger twitter space # Space details ``` ### Common Options | Option | Short | Description | \|--------|-------|-------------| \| `--output` | `-o` | Output format: json, csv, table, markdown | \| `--fields` | `-f` | Comma-separated fields to include | \| `--cursor` | `-c` | Pagination cursor | \| `--count` | `-n` | Maximum results (where applicable) | --- ## Google Commands All Google commands are under `scrapebadger google`. **29 subcommands** cover all 16 Google product APIs. ### Search ```bash theme={null} scrapebadger google search # Google web search (SERP) scrapebadger google images # Image search scrapebadger google videos # Video search scrapebadger google autocomplete # Search suggestions scrapebadger google ai-mode # AI-generated answer (udm=50) scrapebadger google lens # Visual search by image URL ``` ### Search Options | Option | Description | \|---|---| \| `--gl` | Country code (e.g. `us`, `gb`) | \| `--hl` | Language code (e.g. `en`, `fr`) | \| `--num` / `-n` | Number of results | \| `--start` | Page offset (0, 10, 20,...) | \| `--domain` | Google domain (e.g. `google.co.uk`) | \| `--device` | `desktop` or `mobile` | \| `--location` | City-level geo-targeting | \| `--tbs` | Time filter (e.g. `qdr:d` past day) | \| `--safe` | `off`, `medium`, `high` | ### Maps ```bash theme={null} scrapebadger google maps-search # Place search scrapebadger google maps-place --data-id # Place detail (or --place-id) scrapebadger google maps-reviews # Paginated reviews scrapebadger google maps-photos # Place photos scrapebadger google maps-posts # Business posts ``` ### News ```bash theme={null} scrapebadger google news # News article search scrapebadger google news-topics # WORLD, BUSINESS, TECHNOLOGY,... scrapebadger google news-trending # Real-time trending stories ``` ### Hotels ```bash theme={null} scrapebadger google hotels \ --check-in 2026-05-01 --check-out 2026-05-05 --adults 2 scrapebadger google hotels-details \ --check-in 2026-05-01 --check-out 2026-05-05 ``` ### Trends ```bash theme={null} scrapebadger google trends # Interest over time (up to 5 terms) scrapebadger google trends-regions # Interest by region scrapebadger google trends-related # Related topics + queries scrapebadger google trends-trending # Real-time trending searches ``` ### Jobs ```bash theme={null} scrapebadger google jobs "software engineer" \ --location "San Francisco, CA" --job-type FULLTIME --date-posted week ``` ### Shopping ```bash theme={null} scrapebadger google shopping # Product search scrapebadger google shopping --min-price 500 --max-price 2000 --sort-by price_low scrapebadger google shopping-product # Product detail + sellers scrapebadger google shopping-click "" --source ``` The `shopping-click` command resolves the real merchant URL for a product by title. Google has removed direct merchant links from organic Shopping HTML; this command uses an "I'm Feeling Lucky" redirect scoped to the source merchant (via `site:` operator) to materialize the product page URL. Costs **1 credit per call**. ### Patents, Scholar, Finance, Products ```bash theme={null} scrapebadger google patents --inventor Smith --assignee Google scrapebadger google patent US10123456B2 # Full patent detail scrapebadger google scholar --as-ylo 2020 --as-yhi 2024 scrapebadger google finance AAPL:NASDAQ # Stock quote scrapebadger google product-detail # Immersive product ``` ### Common Options Every google command supports `--output/-o` (`json`, `csv`, `table`, `markdown`) and `--fields/-f` (comma-separated field list). ````bash theme={null} # Export top 20 SERP results as CSV scrapebadger google search "python 3.13" --num 20 -o csv > results.csv # Pipe to jq scrapebadger google shopping "laptop" | jq '.results[].title' # Full shopping search → click enrichment workflow scrapebadger google shopping "laptop" | \ jq -r '.results[0] | [.title,.source] | @tsv' | \ while IFS=$'\t' read -r title source; do scrapebadger google shopping-click "$title" --source "$source" done ``` --- ## Vinted Commands All Vinted commands are under `scrapebadger vinted`. ```bash scrapebadger vinted search # Search items scrapebadger vinted item # Item details scrapebadger vinted user # Seller profile scrapebadger vinted user-items # User's listed items scrapebadger vinted brands # Search brands scrapebadger vinted markets # List all markets ```` ### Vinted Options | Option | Short | Description | \|--------|-------|-------------| \| `--market` | `-m` | Market code: fr, de, uk, us, etc. (default: fr) | \| `--page` | `-p` | Page number | \| `--per-page` | | Results per page (max 96) | \| `--price-from` | | Min price filter | \| `--price-to` | | Max price filter | \| `--brands` | | Comma-separated brand IDs | \| `--catalogs` | | Comma-separated catalog (category) IDs — the `catalog[]` value in a Vinted category URL | \| `--colors` | | Comma-separated color IDs | \| `--statuses` | | Comma-separated condition IDs | \| `--order` | | Sort order: relevance, newest\_first, price\_low\_to\_high, price\_high\_to\_low | --- ## Web Scraping Commands All web commands are under `scrapebadger web`. ```bash theme={null} scrapebadger web scrape # Scrape a URL scrapebadger web detect # Detect anti-bot protection scrapebadger web screenshot # Take screenshot scrapebadger web extract # Extract structured data scrapebadger web batch ... # Batch scraping scrapebadger web batch-status # Check batch status ``` ### Web Scrape Options | Option | Description | \|--------|-------------| \| `--js` | Enable JavaScript rendering | \| `--wait-for` | CSS selector to wait for | \| `--timeout` | Timeout in milliseconds | \| `--proxy` | Proxy country code | \| `--format` | Response format: html, markdown, text | ### Web Extract Options | Option | Description | \|--------|-------------| \| `--rules` | CSS/XPath extraction rules as JSON | \| `--ai-rules` | AI extraction rules as JSON | \| `--ai-query` | Freeform AI query about the page | ## Vinted image search CLI 0.15.0 or later: ```bash theme={null} scrapebadger vinted search-by-image --image photo.jpg --market nl --price-to 50 scrapebadger vinted search-by-image --image-url https://example.com/photo.webp --brand-ids 53 ``` Supply exactly one of `--image`, `--image-url` or `--image-base64`. JPEG, PNG and WebP up to 5 MiB are supported. A successful search costs 10 credits. See [Vinted image search](/vinted/image-search) for all filters and pagination. # CLI Overview Source: https://docs.scrapebadger.com/cli/overview Command-line interface for ScrapeBadger — Twitter, Google, Vinted, and Web Scraping from the terminal. # ScrapeBadger CLI A command-line tool for accessing ScrapeBadger APIs directly from your terminal. Supports multiple output formats, pipe-friendly design, and field selection. ## Install ```bash pip theme={null} pip install scrapebadger-cli ``` ```bash uv theme={null} uv tool install scrapebadger-cli ``` ```bash uvx (no install) theme={null} uvx --from scrapebadger-cli scrapebadger --help ``` The package is `scrapebadger-cli`, but the installed command is `scrapebadger`. With `uvx`, always pass `--from scrapebadger-cli` — plain `uvx scrapebadger-cli` fails because no executable matches the package name. ## Quick Start ```bash theme={null} # Set up your API key scrapebadger auth --api-key sb_live_... # Get a Twitter user profile scrapebadger twitter user elonmusk # Search tweets as a table scrapebadger twitter search "AI agents" --output table # Google web search scrapebadger google search "python 3.13" --gl us --num 20 # Google shopping + per-product merchant URL enrichment scrapebadger google shopping "laptop" --max-price 2000 scrapebadger google shopping-click "Lenovo IdeaPad 5" --source "Walmart" # Search Vinted in Germany scrapebadger vinted search "nike shoes" --market de # Scrape a URL with JS rendering scrapebadger web scrape https://example.com --js # Check your credits scrapebadger credits ``` ## Authentication The CLI resolves your API key in this order: 1. `SCRAPEBADGER_API_KEY` environment variable 2. `.env` file in the current directory 3. `~/.config/scrapebadger/config.json` (saved via `scrapebadger auth`) ## Output Formats Every command supports `--output` (`-o`) to choose the format: | Format | Flag | Best For | | - | - | - | | JSON | `-o json` (default) | Piping to `jq`, programmatic use | | CSV | `-o csv` | Spreadsheets, data analysis | | Table | `-o table` | Human-readable terminal output | | Markdown | `-o markdown` | Documentation, reports | ### Field Selection Use `--fields` (`-f`) to include only specific columns: ```bash theme={null} scrapebadger twitter trends -o csv -f name,domain_context ``` ## Commands | Group | Commands | | - | - | | **Account** | `auth`, `credits`, `logout` | | **Twitter** | `user`, `tweets`, `tweet`, `search`, `followers`, `following`, `mentions`, `trends`, `replies`, `quotes`, `retweeters`, `community`, `list`, `space` + more | | **Google** | `search`, `maps-search`, `maps-place`, `maps-reviews`, `maps-photos`, `maps-posts`, `news`, `news-topics`, `news-trending`, `hotels`, `hotels-details`, `trends`, `trends-regions`, `trends-related`, `trends-trending`, `jobs`, `shopping`, `shopping-product`, `shopping-click`, `patents`, `patent`, `scholar`, `autocomplete`, `images`, `videos`, `finance`, `ai-mode`, `lens`, `product-detail` (29 commands covering 16 Google products) | | **Vinted** | `search`, `item`, `user`, `user-items`, `brands`, `markets` | | **Web** | `scrape`, `detect`, `screenshot`, `extract`, `batch`, `batch-status` | ## Pipeline Examples ```bash theme={null} # Export trending topics to CSV scrapebadger twitter trends -o csv > trends.csv # Get followers and pipe to jq scrapebadger twitter followers elonmusk | jq '.[].username' # Scrape a page and extract text scrapebadger web scrape https://example.com --format markdown ``` ## Environment Variables | Variable | Description | | - | - | | `SCRAPEBADGER_API_KEY` | Your API key | | `SCRAPEBADGER_API_URL` | Override the API base URL (default: `https://scrapebadger.com`) | ## Vinted mobile data CLI 0.14.0 adds `scrapebadger vinted mobile-operations` and `scrapebadger vinted mobile --params `. See [Vinted mobile API](/vinted/mobile-api) for copyable examples and all 76 operations. # Credits & Pricing Source: https://docs.scrapebadger.com/credits-and-pricing Understand the ScrapeBadger credit system, pricing tiers, and credit costs per endpoint. ScrapeBadger uses a simple credit-based pricing model. Pay only for what you use with transparent, predictable costs. ## How Credits Work Buy credit packages from your dashboard. Larger packages offer better value per credit. Each API request deducts credits from your balance. Most endpoints cost 1 credit per call. Monitor your credit usage in real-time from your dashboard. Set up alerts for low balance. ## Credit Costs by Endpoint ### Web Scraping | Component | Cost | | - | - | | Scrape — `http` engine (default) | 1 credit | | Scrape — `browser` engine (JS rendering) | 5 credits | | Scrape — Anti-bot solver add-on | +5 credits | | Scrape — AI extraction add-on | +2 credits | | Detect — Fresh scan | 1 credit | | Detect — Cached result (5 min TTL) | 0 credits | Web scraping retries are free — you only pay for the engine that produces the final result. Failed requests cost 0 credits. ### Twitter | Category | Endpoints | Cost | | - | - | - | | Tweets | 11 endpoints | 1 base credit + 1 credit per item returned | | Users | 11 endpoints | 1 base credit + 1 credit per item returned | | Lists | 3 endpoints | 1 base credit + 1 credit per item returned | | Communities | 3 endpoints | 1 base credit + 1 credit per item returned | | Trends | 2 endpoints | 1 base credit + 1 credit per item returned | | Geo | 2 endpoints | 1 base credit + 1 credit per item returned | | Spaces | 2 endpoints | 1 base credit + 1 credit per item returned | **Twitter/X is billed per item.** Each request costs **1 base credit plus 1 credit for every item** (tweet, user, etc.) in the response — so a request that returns N items costs **N + 1** credits. For example, an `advanced_search` call returning 20 tweets costs **21 credits**. The exact amount charged for any request is returned in the **`X-Credits-Used`** response header. Failed requests (4xx/5xx errors) do not consume credits. You are only charged for successful responses. ## Free Credits New accounts receive free credits to get started. Use them to test the API and build your integration before purchasing more. Sign up and get free credits to start building. ## Credit Packages We offer a range of credit packages to suit different needs. Larger packages offer better value per credit. See all available credit packages and pricing. ## FAQ Credits are the unit of measurement for API usage. Each API call consumes a certain number of credits based on the endpoint. No, credits never expire. Once purchased, they remain in your account until you use them. When your credit balance reaches zero, API requests will return a 402 Payment Required error. You can purchase more credits at any time. Credits are non-refundable once purchased. However, if you experience technical issues, contact support and we will work with you. No. Google endpoints cache successful responses for 5 minutes. A repeat of the same endpoint with the same query parameters within that window — or sent while an identical request is still running — is served from the cache at **0 credits** and marked with an `X-Cache: HIT` or `X-Cache: COALESCED` response header. See [Google — Response Caching](/google/overview#response-caching). Yes! Our larger credit packages offer significant discounts. Check the [pricing page](https://scrapebadger.com/pricing) for current rates. *** Need help with billing? Contact us at [support@scrapebadger.com](mailto:support@scrapebadger.com). # Depop Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/depop/overview Scrape Depop second-hand fashion across 10 markets — search items, pull full product detail, and look up seller shops and their listings — as structured JSON. ## Scraper API for Depop Search **second-hand fashion** items, pull **full product detail** (title, description, brand, condition, price, and photos), and look up **seller shops** and their listings across Depop's **10 localised markets** — US, UK, Australia, Ireland, Italy, France, Germany, Spain, Netherlands, and New Zealand. Authentication, anti-bot bypass, and market localisation are handled automatically. ## Key Features One API localised to **US**, **UK**, **AU**, **IE**, **IT**, **FR**, **DE**, **ES**, **NL**, and **NZ**. Pick one with the `market` parameter. Search the Depop catalog and filter by **price**, **brand**, **size**, **colour**, **condition**, and **gender**. Title, description, brand, condition, price, availability, seller dispatch time, image gallery, and seller — for any item. Full [shop profiles](/api-reference/endpoint/depop/get-user) — name, bio, rating, follower count — plus every item a seller has listed. Clean JSON responses with prices, currencies, sizes, brands, conditions, and seller info. Depop is fully browser-rendered. ScrapeBadger renders each page with real-browser sessions — no proxies or CAPTCHAs to manage. ## Market Localisation Depop runs on a **single global host** — `www.depop.com` — localised by a `market` query parameter. The market selects the **country and currency** the catalog and prices are rendered in; the domain never changes. | Market | Country | Currency | | - | - | - | | :us: `us` | United States | USD | | :uk: `gb` / `uk` | United Kingdom | GBP | | :australia: `au` | Australia | AUD | | :ireland: `ie` | Ireland | EUR | | :it: `it` | Italy | EUR | | :fr: `fr` | France | EUR | | :de: `de` | Germany | EUR | | :es: `es` | Spain | EUR | | :netherlands: `nl` | Netherlands | EUR | | :new\_zealand: `nz` | New Zealand | NZD | If no `market` is specified, it defaults to `us` (USD). Use the [`/v1/depop/markets`](/api-reference/endpoint/depop/list-markets) endpoint to get the full list (with country code and currency) programmatically. ## Quick Start ```javascript Node.js theme={null} import ScrapeBadger from "scrapebadger"; const client = new ScrapeBadger({ apiKey: "YOUR_API_KEY" }); const results = await client.depop.search({ query: "nike air max", market: "us", }); console.log(results.products); ``` ```python Python theme={null} from scrapebadger import ScrapeBadger client = ScrapeBadger(api_key="YOUR_API_KEY") results = client.depop.search( query="nike air max", market="us", ) print(results.products) ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/depop/search?query=nike+air+max&market=us" \ -H "x-api-key: YOUR_API_KEY" ``` ## Endpoints | Endpoint | Method | Description | | - | - | - | | [`/v1/depop/search`](/api-reference/endpoint/depop/search-items) | GET | Search a market for fashion items | | [`/v1/depop/products/{slug}`](/api-reference/endpoint/depop/get-product) | GET | Full detail for a single item | | [`/v1/depop/users/{username}`](/api-reference/endpoint/depop/get-user) | GET | Seller shop profile | | [`/v1/depop/users/{username}/products`](/api-reference/endpoint/depop/get-user-products) | GET | Items listed by a seller | | [`/v1/depop/markets`](/api-reference/endpoint/depop/list-markets) | GET | List all supported markets | ## Credit Costs | Endpoint | Cost | | - | - | | Search items | 10 credits | | Get product | 10 credits | | Get user | 10 credits | | Get user products | 10 credits | | List markets | 0 credits | | Failed requests | 0 credits | ## Authentication All requests require your API key in the `X-API-Key` header: ```bash theme={null} curl "https://scrapebadger.com/v1/depop/search?query=vintage+levis" \ -H "X-API-Key: YOUR_API_KEY" ``` ## Anti-Bot Handling Depop serves all of its data through a browser-rendered front end. ScrapeBadger renders each page with real Chrome browser sessions routed through proxies, clearing anti-bot checks automatically. You never need to manage proxies, sessions, or CAPTCHAs. Because every response is served through a real browser, Depop requests take a **few seconds** each — slower than plain-HTTP scrapers. ## Next Steps Full API reference for searching the Depop catalog Retrieve full detail, images, and seller for a specific item *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Depop. "Depop" is a trademark of Depop Limited (an Etsy company), used here only to describe the platform this scraper is designed to work with.* # DuckDuckGo Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/duckduckgo/overview Search the DuckDuckGo web SERP, images, news and videos, pull search suggestions and Instant Answers — no DuckDuckGo API key required. ## Scraper API for DuckDuckGo The ScrapeBadger **DuckDuckGo API** turns DuckDuckGo into a clean JSON feed: the web SERP with ads flagged and the zero-click abstract box, image search with size/color/type/layout/license filters, news with both relative and absolute dates, video search with view counts and embed URLs, search-box autocomplete, the Instant Answer API, and the full region code list. All endpoints are `GET`, live under `https://scrapebadger.com/v1/duckduckgo/*`, and authenticate with the `X-API-Key` header. Credits are charged per request (see the table below) and reported on the `X-Credits-Used` response header. ## Features * **Web search** — organic results with `title`, `url`, `snippet`, `display_url`; ad results are returned and flagged `is_ad` so you can include or exclude them yourself. The zero-click `abstract` box (heading, text, source, image) is attached when DuckDuckGo shows one. * **Image search** — 100 results per page with dimensions, source page, encoding format and discovery date, filterable by `size`, `color`, `image_type`, `layout` and `license`. * **News search** — 30 results per page; every date ships in **both** forms: `date_utc` (Unix seconds) and `date_at` (ISO 8601 UTC), plus DuckDuckGo's own `relative_time` and the `syndicate` it aggregated from. * **Video search** — 60 results per page with publisher, uploader, duration, `view_count`, thumbnails and `embed_url`. * **Autocomplete** — search-box suggestions for a partial query, region-aware. * **Instant Answers** — DuckDuckGo's entity/abstract/definition/direct-answer API for reference queries, with `related_topics`. * **Region targeting** — every search endpoint takes a `region` (DuckDuckGo `kl` code, e.g. `us-en`); `wt-wt` (All Regions, no locale bias) is the default. `/regions` lists all supported codes, free. ## Regions `region` is a DuckDuckGo `kl` code — `country-language`, e.g. `us-en`, `uk-en`, `de-de`, `fr-fr`, `jp-jp`. The default `wt-wt` means **All Regions** (no locale bias). List every supported code with [`/regions`](/api-reference/endpoint/duckduckgo/regions) (free). | Common codes | Region | | - | - | | `wt-wt` | All Regions (default) | | `us-en` | United States | | `uk-en` | United Kingdom | | `de-de` | Germany | | `fr-fr` | France | | `jp-jp` | Japan | ## Credits | Endpoint | Path | Credits | | - | - | - | | Web search | `GET /v1/duckduckgo/search` | 5 | | Image search | `GET /v1/duckduckgo/images` | 5 | | News search | `GET /v1/duckduckgo/news` | 5 | | Video search | `GET /v1/duckduckgo/videos` | 5 | | Autocomplete | `GET /v1/duckduckgo/autocomplete` | 1 | | Instant Answer | `GET /v1/duckduckgo/instant` | 1 | | List regions | `GET /v1/duckduckgo/regions` | 0 | ## Quickstart ```bash cURL theme={null} curl "https://scrapebadger.com/v1/duckduckgo/search?query=web+scraping®ion=us-en" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/duckduckgo/search?" + new URLSearchParams({ query: "web scraping", region: "us-en", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); console.log(data.results.length, "results"); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/duckduckgo/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "query": "web scraping", "region": "us-en", }, ) print(len(res.json()["results"]), "results") ``` ## Pagination Every search endpoint pages with a `page` parameter and returns `has_next` — page on that, not on `result_count`. | Surface | Max page | Results per page | | - | - | - | | `/search` | 25 | \~10–30 | | `/images` | 10 | 100 | | `/news` | 10 | 30 | | `/videos` | 10 | 60 | ## Other notes * **SafeSearch** — `safesearch` accepts `on`, `moderate` (default) or `off` on `/search`, `/images`, `/news` and `/videos`. * **Time filters** — `timelimit` (`day`, `week`, `month`, `year`) narrows `/search` and `/news` to recent results; omit it for all time. * **Instant Answers are entity-shaped.** `/instant` answers reference queries (people, places, definitions, calculations); most long-tail search phrases return an empty payload — that is DuckDuckGo's behaviour, not an error. Use `/search` for general queries. * **Datetimes ship in both forms** — news dates come as `date_utc` (Unix seconds) and `date_at` (ISO 8601 UTC string). ## Errors | Status | Meaning | | - | - | | `422` | Anti-bot challenge — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — not billed. | Start from [`/autocomplete`](/api-reference/endpoint/duckduckgo/autocomplete) (1 credit) to expand a partial term into real DuckDuckGo queries, then run [`/search`](/api-reference/endpoint/duckduckgo/search) on each one and merge on `url`. *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by DuckDuckGo. "DuckDuckGo" is a trademark of DuckDuckGo, Inc., used here only to describe the platform this scraper is designed to work with.* # eBay Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/ebay/overview Scrape eBay active listings, item details, reviews, and seller data across 18 marketplaces with structured JSON responses. ## Scraper API for eBay Search active listings by keyword or by image, fetch full item detail, list reviews, and retrieve seller profiles, storefronts, and feedback from eBay — one of the world's largest online marketplaces. The API handles authentication, anti-bot bypass, and marketplace routing automatically. ## Key Features Access all major eBay marketplaces including US, UK, DE, FR, IT, ES, AU, CA, and more. Search, item detail, reviews and seller data resolve across every supported marketplace from a single `domain` parameter. Automatic session management, Chrome TLS impersonation, and fingerprint rotation to avoid blocks. Prices, conditions, item specifics, shipping options, returns, seller info, ratings, and sold counts. Live auction fields — bid count, time remaining, current high bid, absolute end time, and Buy It Now price — on search cards and item detail. Requests are routed through proxies matching the target marketplace for accurate pricing and availability. First-class support via the ScrapeBadger Node.js and Python SDKs. eBay no longer exposes public **watcher counts**, so the `watchers` field is often `null` on search, seller-items, and item-detail responses. `sold_count` remains available on item detail and is the reliable signal for demand. Completed/sold **price history** is available via [`/v1/ebay/completed`](/api-reference/endpoint/ebay/completed), which returns items that have sold with their sale price and date. ## Supported Marketplaces eBay operates across 18 country domains. Use the `domain` query parameter to target a specific one. | Market | Domain | Market | Domain | | - | - | - | - | | :us: `com` | ebay.com | :gb: `co.uk` | ebay.co.uk | | :de: `de` | ebay.de | :fr: `fr` | ebay.fr | | :it: `it` | ebay.it | :es: `es` | ebay.es | | :australia: `com.au` | ebay.com.au | :canada: `ca` | ebay.ca | | :at: `at` | ebay.at | :switzerland: `ch` | ebay.ch | | :be: `be` | ebay.be | :ireland: `ie` | ebay.ie | | :netherlands: `nl` | ebay.nl | :poland: `pl` | ebay.pl | | :hong\_kong: `com.hk` | ebay.com.hk | :singapore: `com.sg` | ebay.com.sg | | :malaysia: `com.my` | ebay.com.my | :philippines: `ph` | ebay.ph | If no `domain` is specified, it defaults to `com`. Country-style aliases also work (`us` → `com`, `uk`/`gb` → `co.uk`, `au` → `com.au`, `hk`/`sg`/`my`). Use the [`/v1/ebay/markets`](/api-reference/endpoint/ebay/list-markets) endpoint to get the full list (with currency, locale, and site id) programmatically. ## Quick Start ```javascript Node.js theme={null} import ScrapeBadger from "scrapebadger"; const client = new ScrapeBadger({ apiKey: "YOUR_API_KEY" }); const results = await client.ebay.search({ query: "nintendo switch oled", domain: "com", page: 1, }); console.log(results.results); ``` ```python Python theme={null} from scrapebadger import ScrapeBadger client = ScrapeBadger(api_key="YOUR_API_KEY") results = client.ebay.search( query="nintendo switch oled", domain="com", page=1, ) print(results.results) ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/ebay/search?query=nintendo+switch+oled&domain=com&page=1" \ -H "x-api-key: YOUR_API_KEY" ``` ## Endpoints | Endpoint | Method | Description | | - | - | - | | [`/v1/ebay/search`](/api-reference/endpoint/ebay/search) | GET | Search a marketplace for active listings | | [`/v1/ebay/search/by-image`](/api-reference/endpoint/ebay/search-by-image) | POST | Search active listings by image — eBay's own visual search | | [`/v1/ebay/completed`](/api-reference/endpoint/ebay/completed) | GET | Search completed (sold) listings — sold-price history | | [`/v1/ebay/items/{item_id}`](/api-reference/endpoint/ebay/get-item-detail) | GET | Full detail for a single listing | | [`/v1/ebay/items/{item_id}/reviews`](/api-reference/endpoint/ebay/get-item-reviews) | GET | Catalog product reviews for a listing | | [`/v1/ebay/sellers/{username}`](/api-reference/endpoint/ebay/get-seller) | GET | Seller public profile | | [`/v1/ebay/sellers/{username}/items`](/api-reference/endpoint/ebay/get-seller-items) | GET | A seller's active listings | | [`/v1/ebay/sellers/{username}/feedback`](/api-reference/endpoint/ebay/get-seller-feedback) | GET | A seller's recent feedback comments | | [`/v1/ebay/categories/{category_id}/items`](/api-reference/endpoint/ebay/browse-category) | GET | List listings within a category | | [`/v1/ebay/categories`](/api-reference/endpoint/ebay/list-categories) | GET | List top-level category aliases | | [`/v1/ebay/autocomplete`](/api-reference/endpoint/ebay/autocomplete) | GET | Keyword autocomplete suggestions | | [`/v1/ebay/markets`](/api-reference/endpoint/ebay/list-markets) | GET | List all supported marketplaces | ## Credit Costs | Endpoint | Cost | | - | - | | Search | 5 credits | | Search by image | 10 credits | | Completed / sold | 5 credits | | Get item detail | 5 credits | | Get item reviews | 10 credits | | Get seller | 5 credits | | Seller items | 5 credits | | Seller feedback | 10 credits | | Browse category | 5 credits | | Autocomplete | 1 credit | | List categories | 0 credits | | List markets | 0 credits | | Failed requests | 0 credits | ## Authentication All requests require your API key in the `X-API-Key` header: ```bash theme={null} curl "https://scrapebadger.com/v1/ebay/search?query=laptop" \ -H "X-API-Key: YOUR_API_KEY" ``` ## Anti-Bot Handling eBay protects its catalog with IP-reputation scoring, TLS/HTTP-2 fingerprinting, and per-domain server-side rendering. ScrapeBadger clears these automatically using Chrome TLS impersonation on sessions matched to the target marketplace. You never need to manage proxies, sessions, or CAPTCHAs. For accurate pricing and availability, requests are routed through proxies in the marketplace's country. This is handled automatically based on the `domain` parameter. ## Auction Data Auction listings are fully supported across search cards and item detail. When a listing is an auction (`is_auction` is `true`), these fields are populated: | Field | Where | Description | | - | - | - | | `bids` | cards + detail | Number of bids placed so far. | | `time_left` | cards + detail | Relative time remaining, e.g. `12h 16m`. | | `current_bid` | cards + detail | Current high bid (an `EbayPrice`, mirrors `price`). | | `end_time_utc` | detail | Absolute end time as a Unix timestamp (float seconds). | | `end_time_at` | detail | Absolute end time as an ISO-8601 Z string, e.g. `2026-06-22T19:50:51Z`. | | `buy_it_now_price` | detail | Buy It Now price (an `EbayPrice`); `null` for pure auctions. | For non-auction (fixed-price) listings, `current_bid`, `end_time_utc`, and `end_time_at` are `null`, and `buy_it_now_price` mirrors `price`. Use [`buying_format=auction`](/api-reference/endpoint/ebay/search) on search, or [`sort_by=ending_soonest`](/api-reference/endpoint/ebay/search), to surface auctions. ## Next Steps Full API reference for searching the eBay catalog Full listing detail including price, condition, specifics and seller *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by eBay. "eBay" is a trademark of eBay Inc., used here only to describe the platform this scraper is designed to work with.* # Facebook Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/facebook/overview Facebook Marketplace listings, search, Pages, profiles, Groups, posts, comments and the Ad Library as clean JSON — no Meta developer app, App Review or access token required. ## Scraper API for Facebook The ScrapeBadger **Facebook API** turns `facebook.com` into a clean JSON feed: **Marketplace** listings, global search across seven tabs, Page and profile detail, Group metadata and feeds, post and comment threads, and the public **Ad Library**. All endpoints are `GET`, live under `https://scrapebadger.com/v1/facebook/*`, and authenticate with the `X-API-Key` header. Credits are charged per request (see the table below) and reported on the `X-Credits-Used` response header. **Global keyword Search** (`/search`, `/search/pages`, `/search/people`, `/search/groups`, `/search/posts`, `/search/places`, `/search/events`) is **temporarily unavailable** while we expand capacity and currently returns `503 {"error": "temporarily_unavailable"}`. Everything else — Marketplace, Pages, profiles, Groups, posts, comments and the Ad Library — is live. Facebook's own Graph API exposes **no Marketplace inventory at any price**, and reading Pages, Groups or posts through Graph requires an owned asset plus an approved permission. This API needs none of that — no Meta developer app, no App Review, no OAuth tokens. ## Features * **Marketplace search** — the headline surface. Keyword search across the largest classifieds inventory in the world, with filters for price range, age of listing, condition, delivery method and sort order. Returns `price_amount` + `currency`, geo coordinates, photo galleries, condition subtitles, `is_sold` / `is_pending` state and the seller actor. * **Marketplace category browse** — walk a whole vertical (`vehicles`, `propertyrentals`, `electronics`, `apparel`, …) in one location, with the same price and sort filters. * **Marketplace item detail** — the full listing: description body, complete `photos[]` gallery, vertical-specific `attributes` (vehicle make/model/ mileage, property beds/baths) and seller profile. * **Search across seven tabs** — one mixed `all` tab plus `pages`, `people`, `groups`, `posts`, `places` and `events`. Every result carries a `type`, an id and a canonical URL you can hand straight to a detail endpoint. * **Pages & profiles** — name, category, verification, cover photo, follower / like counts, and the About tile (website, phone, email, address, rating), plus paginated timelines. * **Groups** — privacy, member count, description, creation date, and the group feed with full post objects. * **Posts & comments** — a single post by numeric id, `pfbid` string, `permalink.php` form or reel URL, with attachments, reaction breakdown (`top_reactions[]`), share and comment counts — and the comment thread with author, reactions and reply counts. * **Ad Library** — competitive-intelligence search over Facebook's public ad archive: creative copy, snapshot URL, flight dates, `publisher_platforms[]`, images/videos and the CTA — plus advertiser Page search, Page transparency info (owner, admin countries, history, political ad spend) and EU DSA transparency (reach and demographics) on ad lookups with an EU `country`. ## Markets Marketplace is **location-scoped** by slug and the Ad Library is **country-scoped** by ISO code. Search, Pages, Groups and posts are global and need no market parameter. | Surface | Parameter | Default | Catalog | | - | - | - | - | | Marketplace | `location` | `nyc` | [`/marketplace/locations`](/api-reference/endpoint/facebook/marketplace-category) — `nyc`, `la`, `chicago`, `houston`, `seattle`, `sanfrancisco`, `miami`, `atlanta`, `london`, `toronto`, `sydney` (any city slug works) | | Ad Library | `country` | `US` | Any ISO 3166-1 alpha-2 code | | Search / Pages / Groups / Posts | — | global | — | ## Credits | Endpoint | Path | Credits | | - | - | - | | Marketplace search | `GET /v1/facebook/marketplace/search` | 5 | | Marketplace category | `GET /v1/facebook/marketplace/category/{category}` | 5 | | Marketplace item | `GET /v1/facebook/marketplace/item/{item_id}` | 5 | | Marketplace locations | `GET /v1/facebook/marketplace/locations` | 0 | | Marketplace categories | `GET /v1/facebook/marketplace/categories` | 0 | | Search (all tabs) | `GET /v1/facebook/search` · `/search/{tab}` | 5 | | Get Page / profile | `GET /v1/facebook/pages/{identifier}` · `/profiles/{identifier}` | 5 | | Page / profile posts | `GET /v1/facebook/pages/{identifier}/posts` · `/profiles/{identifier}/posts` | 5 | | Get group | `GET /v1/facebook/groups/{group_id}` | 5 | | Group posts | `GET /v1/facebook/groups/{group_id}/posts` | 5 | | Get post | `GET /v1/facebook/posts/{post_id}` | 5 | | Post comments | `GET /v1/facebook/posts/{post_id}/comments` | 10 | | Ad Library search | `GET /v1/facebook/ads/search` | 5 | | Get ad | `GET /v1/facebook/ads/{ad_archive_id}` | 5 | | Ad Library page search | `GET /v1/facebook/ads/pages/search` | 5 | | Ad Library page info | `GET /v1/facebook/ads/pages/{page_id}` | 5 | ## Quickstart ```bash cURL theme={null} curl "https://scrapebadger.com/v1/facebook/marketplace/search?query=macbook%20pro&location=nyc&max_price=1200" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/facebook/marketplace/search?" + new URLSearchParams({ query: "macbook pro", location: "nyc", max_price: "1200", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); console.log(data.listings.length, "listings"); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/facebook/marketplace/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "query": "macbook pro", "location": "nyc", "max_price": 1200, }, ) print(len(res.json()["listings"]), "listings") ``` ## Pagination Every list endpoint uses Facebook's Relay **cursor** pagination — there are no page numbers. Read `end_cursor` from the response and pass it back as the `after` query parameter while `has_next_page` is `true`. ```python Python theme={null} cursor, page = None, 0 while True: res = requests.get( "https://scrapebadger.com/v1/facebook/marketplace/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "macbook pro", "location": "nyc", "after": cursor}, ).json() print(page, len(res["listings"])) if not res["has_next_page"]: break cursor, page = res["end_cursor"], page + 1 ``` ## Timestamps Every datetime ships in **both** forms: `*_utc` (Unix seconds, e.g. `creation_time_utc`) and `*_at` (ISO 8601 UTC string, e.g. `created_at`). Start from [`/marketplace/search`](/api-reference/endpoint/facebook/marketplace-search) or [`/search`](/api-reference/endpoint/facebook/search) to discover entities, then take the returned `id` / `url` into [`/marketplace/item/{item_id}`](/api-reference/endpoint/facebook/marketplace-item), [`/pages/{identifier}`](/api-reference/endpoint/facebook/get-page) or [`/groups/{group_id}`](/api-reference/endpoint/facebook/get-group) for full detail — search results are deliberately shallow discovery records. *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Facebook or Meta. "Facebook" is a trademark of Meta Platforms, Inc., used here only to describe the platform this scraper is designed to work with.* # Gemini API Overview Source: https://docs.scrapebadger.com/gemini/overview Ask the real gemini.google.com a question and get the answer back as structured JSON — with the web sources it cited, anchored to the exact text they support. No Google account or API key required. ## Overview The ScrapeBadger **Gemini API** sends a prompt to **the real `gemini.google.com`** — not the Gemini developer API — and returns the answer as structured JSON, including the web sources Gemini actually grounded on and cited. Requests are **anonymous**: no Google account, no Gemini API key, no billing relationship with Google. You see what a logged-out user in your chosen country sees, answered by the anonymous surface's **Gemini Flash-Lite** model. All endpoints live under `https://scrapebadger.com/v1/gemini/*` and authenticate with the `X-API-Key` header. `/ask` and `/brand-visibility` accept both `GET` (query params) and `POST` (JSON body). Credits are charged per request and reported on the `X-Credits-Used` response header. **Answers are a live render of gemini.google.com, not a cached lookup** — the clock includes Gemini composing the answer and, when it grounds, running its own web search. Set your HTTP client timeout to **60 s or more**; the default 5–10 s timeout in most SDKs will abort the call. ## Features * **Real Gemini answers** — the full text as rendered on gemini.google.com, plus a Markdown variant when one is available. * **Anchored citations** — every citation carries `start_index` / `end_index` character offsets into `answer` and the `matched_text` it supports, so you can highlight exactly which sentence a source backs. * **The full search trail** — `search_results` is everything Gemini retrieved, each flagged `cited: true/false`. `citations` is the subset it actually referenced. Most APIs only give you the second list. * **Did it really search?** — `web_search_triggered` tells you whether Gemini grounded the answer with a web search or answered from its own weights. Force it with `web_search=force`, or suppress it with `web_search=off`. * **Brand visibility (AEO/GEO) built in** — one call returns mention counts, position score, share of voice against named competitors, and whether your domain was cited. No separate subscription. * **Country control** — `country` picks the egress country, so you can compare the answer a user in `DE` gets against the one in `US`. * **No image input** — `image_url` and `image_base64` return **422** and are not billed. Signed-out Gemini accepts the upload and then refuses to answer about it (`PERMISSION_DENIED` from its own generate call), so we fail immediately rather than charge for a request that cannot succeed. Use [ChatGPT `/ask`](/chatgpt/overview) for image input. Image *generation* is not available either: anonymous gemini.google.com gates that behind a login. ## Honesty caveat Each request is a **single, fresh, anonymous question**. There is no conversation memory, no multi-turn follow-up, no model selection, no streaming, and **no image input or output** — `conversation_id` and `message_id` identify the one-shot exchange, they are not handles you can continue from. Attaching a picture returns 422; ChatGPT's `/ask` takes one. The anonymous surface always answers with a **Gemini Flash-Lite** model; the `model` field reports which build answered, it is **not** a request parameter. Gemini is non-deterministic: the same prompt asked twice can produce different wording and different sources. For monitoring use cases, sample repeatedly and aggregate rather than trusting a single call. ## Credits | Endpoint | Path | Credits | | - | - | - | | Ask | `GET`/`POST` `/v1/gemini/ask` | 20 | | Brand visibility | `GET`/`POST` `/v1/gemini/brand-visibility` | 25 | | Health | `GET`/`HEAD` `/v1/gemini/health` | 0 | At the PAYG rate of $0.15 per 1K credits, an `/ask` call is **$0.003\*\* — **\$3.00 per 1,000 answers**. Subscription tiers cut that substantially. Non-2xx responses are never billed. ## Quickstart ```bash cURL theme={null} curl "https://scrapebadger.com/v1/gemini/ask?prompt=What%20are%20the%20best%20web%20scraping%20APIs%20in%202026%3F" \ -H "X-API-Key: YOUR_API_KEY" \ --max-time 60 ``` ```javascript Node.js theme={null} const res = await fetch("https://scrapebadger.com/v1/gemini/ask", { method: "POST", headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ prompt: "What are the best web scraping APIs in 2026?", country: "US", web_search: "force", }), signal: AbortSignal.timeout(60_000), }); const data = await res.json(); console.log(data.answer); console.log(data.source_domains); ``` ```python Python theme={null} import requests res = requests.post( "https://scrapebadger.com/v1/gemini/ask", headers={"X-API-Key": "YOUR_API_KEY"}, json={ "prompt": "What are the best web scraping APIs in 2026?", "country": "US", "web_search": "force", }, timeout=60, ) data = res.json() print(data["answer"]) print(data["source_domains"]) ``` ## What you can build Track whether Gemini names your brand for the prompts your buyers ask, how early it names you, and how you rank against competitors — with [`/brand-visibility`](/api-reference/endpoint/gemini/brand-visibility). Find which domains Gemini trusts for a topic. `search_results` shows everything it retrieved; `cited` shows what survived into the answer. Compare answers across countries, or with `web_search` forced on and off, to separate what Gemini knows from what it looked up. Ask the same prompt on the [ChatGPT API](/chatgpt/overview) and here — both return the same response shape, so comparing how each model answers and who each model cites is a diff, not a project. ## FAQ No. This drives the public `gemini.google.com` web interface as an anonymous visitor. You do not need a Google account, a Gemini API key, or a Google AI subscription — and answers include the web citations Gemini showed, which the developer API does not return in this form. Because a real answer is being generated, and when Gemini grounds it runs its own web search first. Budget a 60 s client timeout and run calls concurrently rather than in a tight sequence. No. Every request is a fresh, standalone question with no memory of previous calls. Put all necessary context in the single `prompt` (up to 4,096 characters). No. The anonymous gemini.google.com surface always answers with a Gemini Flash-Lite model. The `model` field in a response reports which build answered — but you cannot request a specific one. Check `web_search_triggered`. If it is `false`, Gemini answered from its training data and there were no sources to cite — that is normal for general-knowledge prompts. Set `web_search=force` if you always want it to ground the answer. No. Gemini is non-deterministic, and the live web changes. For tracking, sample the same prompt on a schedule and look at the trend, not a single result. It changes the egress country of the request, which affects the localised results Gemini retrieves and can change the answer's emphasis and language. Pass any ISO-3166 alpha-2 code; the default is `US`. You get `{"detail": {"code": ..., "message": ...}}` with an HTTP status of 422, 429 or 502 depending on the cause. **Non-2xx responses are never billed**, so a retry costs you nothing extra beyond the successful call. Start with [`/ask`](/api-reference/endpoint/gemini/ask) to see the shape of a real answer, then move to [`/brand-visibility`](/api-reference/endpoint/gemini/brand-visibility) once you know which prompts matter for your market. # Google Ads Transparency API Overview Source: https://docs.scrapebadger.com/google-ads-transparency/overview Search the Google Ads Transparency Center as JSON — creatives by advertiser or domain, per-creative media and run dates, advertiser lookup, and disclosed political spend by region. ## Overview The ScrapeBadger **Ads Transparency API** turns Google's Ads Transparency Center into JSON: every creative an advertiser has run, with its format, media, first- and last-shown dates and days-shown count; the detail of a single creative including its size variations; advertiser lookup by name or domain; and the disclosed spend, ad mix and per-day spend curve for an advertiser in a region. All endpoints are `GET`, live under `https://scrapebadger.com/v1/google/ads/*`, and authenticate with the `X-API-Key` header. Credits are charged per request (see the table below) and reported on the `X-Credits-Used` response header. ## Features * **Creative search** — by `advertiser_id` or free-text `query`, with format and date-window filtering, and token pagination up to 100 per page. * **Creative detail** — media URL, preview HTML, every rendered size `variation`, run dates and the target domain. * **Advertiser lookup** — resolve a brand name or domain to the `advertiser_id` the other endpoints take. * **Political disclosure** — for advertisers who run political ads, Google's disclosed spend, currency, ad count and per-day spend curve for one region. * **Dual timestamps** — every date ships twice: `*_utc` (Unix seconds) and `*_at` (ISO 8601 UTC). ## Finding an advertiser **Free-text `query` on `/ads/search` is domain-based.** It matches verified advertiser domains such as `nike.com`, not brand names. Searching `Nike` usually returns nothing. For a brand name, go through [`/ads/advertisers`](/api-reference/endpoint/google-ads-transparency/search-advertisers) first and use the `advertiser_id` it returns. Its name match has no typo tolerance either: add `fuzzy=true` to find misspelled and look-alike advertisers, including those behind look-alike domains. ```bash theme={null} # 1. name -> advertiser_id curl "https://scrapebadger.com/v1/google/ads/advertisers?query=nike®ion=US" \ -H "X-API-Key: YOUR_API_KEY" # 2. advertiser_id -> creatives curl "https://scrapebadger.com/v1/google/ads/search?advertiser_id=AR01614014350098432001®ion=US" \ -H "X-API-Key: YOUR_API_KEY" ``` ## Regions `region` is an ISO 3166-1 alpha-2 code (`US`, `DE`, `GB`, …) naming the region the ad was served in, or `anywhere` for no region filter. Google filters by its own numeric geo-target criteria ids internally; the mapping is handled for you. Spend disclosure is **region-scoped**: `anywhere` returns nothing on `/ads/advertiser`, so that endpoint falls back to `US`. ## Filter honesty Not every filter can be pushed upstream, and this API tells you which ones were applied instead of pretending. `/ads/search` returns a `filters_applied` object: | Filter | Where it is applied | | - | - | | `region`, `advertiser_id`, `query` | Pushed into Google's RPC. | | `format`, `start_date`/`end_date` | Applied here, over the returned page — Google answers an unknown request field with `200` and an empty body, and a wrong guess would look like "this advertiser has no ads". | | `platform`, `political` | **Not applied at all.** Validated, then reported as `false` in `filters_applied`. | Because `format` and the date window are applied after the fetch, `returned_results` can be smaller than `num` while `next_page_token` is still set. Keep paging. ## Credits | Endpoint | Path | Credits | | - | - | - | | Search creatives | `GET /v1/google/ads/search` | 10 | | Creative detail | `GET /v1/google/ads/creative` | 5 | | Search advertisers | `GET /v1/google/ads/advertisers` | 5 (15 with `fuzzy=true`) | | Advertiser detail | `GET /v1/google/ads/advertiser` | 5 | ## Quickstart ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google/ads/search?query=nike.com®ion=US&num=40" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/google/ads/search?" + new URLSearchParams({ query: "nike.com", region: "US", num: "40" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); console.log(data.returned_results, "creatives of", data.total_results); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/google/ads/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "nike.com", "region": "US", "num": 40}, ) data = res.json() print(data["returned_results"], "creatives of", data["total_results"]) ``` ## Errors | Status | Meaning | | - | - | | `400` | Neither `advertiser_id` nor `query` given; unknown platform, format, region or date. | | `404` | No such creative for that advertiser, or no disclosure for that advertiser and region. | | `502` | Upstream Transparency Center failure — **not billed**. | # Google Play Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/google-play/overview Turn the Google Play Store into JSON — app detail with the full ratings histogram, install bands, IAP range, the Data Safety declaration and permission tree, plus search, reviews, similar apps, developer catalogues and category browse across 47 storefronts. ## Scraper API for Google Play The ScrapeBadger **Google Play API** reads `play.google.com` server-side and returns clean JSON: full app detail (ratings histogram, install bands, pricing and in-app-purchase range, developer legal entity, screenshots, version and what's-new), keyword search, paginated reviews with developer replies, the Android permission tree, the similar-apps rail, a developer's catalogue and category browse. All endpoints are `GET`, live under `https://scrapebadger.com/v1/google-play/*`, and authenticate with the `X-API-Key` header. Credits are charged per request (see the table below) and reported on the `X-Credits-Used` response header. ## Features * **App detail in one call** — `score`, `ratings`, `reviews`, the 1–5 star `histogram`, `installs` with `min_installs`/`max_installs` bands, `price` plus `offers_iap` and `iap_range`, `contains_ads`, genre, content rating, media, `version`, `android_version`, `recent_changes` (what's new), the `data_safety` declaration, the `permissions` tree and the similar-apps rail. * **Reviews** — Play's own review RPC, up to 150 per page, sorted by `newest`, `rating` or `helpfulness`, with developer replies and both timestamp forms. * **Permissions** — every Android permission the app declares, grouped as Play groups them, for 3 credits. * **Discovery** — `/search`, `/apps/{id}/similar`, `/developers/{id}` and `/categories/{id}` all return the same rich `AppCard` shape, so a list result rarely needs a follow-up detail fetch just to rank or filter. * **Dual timestamps** — every date ships twice: `*_utc` (Unix seconds, for maths) and `*_at` (ISO 8601 UTC, for humans). ## Markets and languages Play is one global host, so storefront and language are **independent**: * `country` sets the `gl` storefront — pricing, availability and ranking. * `lang` sets the `hl` content language — description, what's-new and reviews. [`GET /v1/google-play/markets`](/api-reference/endpoint/google-play/list-markets) (free) returns the 47 supported storefront countries and 31 content languages. [`GET /v1/google-play/categories`](/api-reference/endpoint/google-play/list-categories) (free) returns the 60 category ids that `/categories/{id}` accepts. ## Credits | Endpoint | Path | Credits | | - | - | - | | Search apps | `GET /v1/google-play/search` | 5 | | App detail | `GET /v1/google-play/apps/{app_id}` | 5 | | App reviews | `GET /v1/google-play/apps/{app_id}/reviews` | 5 | | App permissions | `GET /v1/google-play/apps/{app_id}/permissions` | 3 | | Similar apps | `GET /v1/google-play/apps/{app_id}/similar` | 5 | | Developer apps | `GET /v1/google-play/developers/{developer}` | 5 | | Browse category | `GET /v1/google-play/categories/{category_id}` | 5 | | Top charts | `GET /v1/google-play/collections/{collection}` | 5 | | List categories | `GET /v1/google-play/categories` | 0 | | List markets | `GET /v1/google-play/markets` | 0 | ## Quickstart ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google-play/apps/com.whatsapp?country=US&lang=en" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/google-play/apps/com.whatsapp?" + new URLSearchParams({ country: "US", lang: "en" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const app = await res.json(); console.log(app.title, app.score, app.installs); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/google-play/apps/com.whatsapp", headers={"X-API-Key": "YOUR_API_KEY"}, params={"country": "US", "lang": "en"}, ) app = res.json() print(app["title"], app["score"], app["installs"]) ``` ## Top charts **`/collections/{collection}` returns `422`.** Google no longer server-renders the top-chart ranking — the category page carries the chart *tabs* but their item list is filled in client-side, so no server-side ranking exists to read. The endpoint answers `422` (which is **not billed**) with a message saying so, rather than quietly returning the page's editorial rails as if they were a chart. Use [`/categories/{category_id}`](/api-reference/endpoint/google-play/browse-category) for a category's apps in Play's own order. ## Result depth * **`/search`** returns the \~30 results Play renders server-side. There is no `page` parameter: Play's search has no page number, and its infinite-scroll continuation is a cluster RPC Google no longer accepts from outside its own client. Widen a result set with `/apps/{id}/similar` and `/developers/{id}`. * **`/developers/{developer}`** returns the first rail Play renders — around 10 apps for a publisher with dozens. * **`/categories/{category_id}`** returns every app across all of the category page's editorial rails, deduped — around 100 apps for a broad category. * **`/apps/{id}/similar`** returns the detail page's rail, capped by Play at roughly a dozen; `similar_apps_url` on the detail response is the "see more" cluster page. ## Errors | Status | Meaning | | - | - | | `400` | Unknown collection id. | | `404` | The app, developer or category does not exist in that storefront. | | `422` | Play returned no usable data (challenge, or a client-rendered chart) — **not billed**. | | `502` | Unexpected upstream failure — **not billed**. | App detail already carries the permission tree, the Data Safety card and the similar-apps rail — the sibling routes are only needed when you want *more* reviews, a standalone permissions call, or the full similar-apps cluster. *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Google. "Google Play" is a trademark of Google LLC, used here only to describe the platform this scraper is designed to work with.* # Google Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/google/overview Structured JSON APIs for 16 Google product APIs — Search, Maps, News, Hotels, Trends, Jobs, Shopping, Patents, Scholar, Images, Videos, Finance, AI Mode, Lens, and Products. ## Scraper API for Google Programmatic access to **16 Google product APIs** with structured JSON responses. The ScrapeBadger Google Scraper handles SearchGuard, proxy rotation, cookie warmup, and IP rotation on 429 automatically — you just call the endpoint. ## Products Organic results, ads, knowledge graph, People Also Ask, People also search for, related searches, AI overview, and pagination. Place search, business details, reviews, photos, and posts from Google Maps. Article search, topic feeds, and trending stories from Google News. Property search and detailed listings with prices, ratings, and amenities. Interest over time, regional breakdowns, related queries, and real-time trending. Job listings aggregated across the web with filters for type, date, and location. Product listings with prices, ratings, filters — plus per-product merchant URL enrichment. Patent document search and full-detail retrieval by patent number. Academic paper search with year-range and citation filters. Google search suggestion lookup for query prefixes. Image search with size, color, and type filters. Video search across Google's video index. Stock, index, crypto, and currency quotes with change data. Google's generative AI answers (udm=50) as structured text blocks (prose, headings, comparison tables, lists), source references, a compact Markdown rendering, and the raw answer HTML. Visual image search — find similar products and images from a URL. ## Anti-Bot Handling Google deployed **SearchGuard** in January 2025 — a JS challenge that blocks raw HTTP. The ScrapeBadger Google Scraper bypasses it with a cookie-warmup pattern: 1. First request attempts a **fast HTTP fetch** with cached cookies (\~0.2s fast path) 2. If a SearchGuard challenge is detected, a **browser warmup** solves it 3. Subsequent requests reuse the warm cookies over HTTP for speed 4. On **429 or CAPTCHA**, the cached residential proxy session is invalidated to rotate the exit IP, then the retry loop continues (up to 3 IP rotations per request) ## 185 Google Domains The SERP endpoint accepts any of Google's 185 country domains via the `domain` parameter: ```bash theme={null} curl "https://scrapebadger.com/v1/google/search?q=laptop&domain=google.co.uk&gl=gb&hl=en" \ -H "x-api-key: YOUR_API_KEY" ``` ## Quick Start ```javascript Node.js theme={null} import { ScrapeBadger } from "scrapebadger"; const client = new ScrapeBadger({ apiKey: "YOUR_API_KEY" }); // Web search const serp = await client.google.search.search({ q: "python 3.13" }); for (const r of serp.organic_results) { console.log(r.title, r.link); } // Shopping search + per-product merchant URL enrichment const products = await client.google.shopping.search({ q: "laptop" }); const first = products.results[0]; const enriched = await client.google.shopping.click({ title: first.title, source: first.source, }); console.log("Merchant URL:", enriched.merchant_url); ``` ```python Python theme={null} from scrapebadger import ScrapeBadger async with ScrapeBadger(api_key="YOUR_API_KEY") as client: # Web search serp = await client.google.search.search("python 3.13") for r in serp["organic_results"]: print(r["title"], r["link"]) # Maps search places = await client.google.maps.search("coffee shops in san francisco") # Shopping search + click enrichment products = await client.google.shopping.search("laptop") first = products["results"][0] enriched = await client.google.shopping.click( title=first["title"], source=first["source"], ) print("Merchant URL:", enriched["merchant_url"]) ``` ```bash cURL theme={null} # Web search curl "https://scrapebadger.com/v1/google/search?q=python+3.13&gl=us&hl=en" \ -H "x-api-key: YOUR_API_KEY" # Shopping search curl "https://scrapebadger.com/v1/google/shopping/search?q=laptop" \ -H "x-api-key: YOUR_API_KEY" # Per-product merchant URL enrichment curl "https://scrapebadger.com/v1/google/shopping/product/click?title=Lenovo+IdeaPad+5&source=Walmart" \ -H "x-api-key: YOUR_API_KEY" ``` ## Search result blocks Each block below is returned when Google shows it for your query. | Field | What it holds | | - | - | | `related_questions` | The People Also Ask questions shown on the page, usually four, as `question` and `rank`. Google loads each answer only when a question is clicked, so `title`, `link` and `snippet` are `null`. You can't expand the block to load more questions. | | `people_also_search_for` | Every item under a "People also search for" heading, as `name`, `link` and `thumbnail`. This covers the list of refined searches at the foot of the page and the entity carousel in a knowledge panel. Only carousel items carry a `thumbnail`. The block is matched on its English heading, so it fills with `hl=en`. | | `related_searches` | The refined searches at the foot of the page, as `query` and `link`. Google's tabs (AI Mode, Shopping) and knowledge panel buttons (Address, Phone) are not included. | | `local_results` | The places in a local pack (the map with a list of places). A single business or landmark appears in `knowledge_graph` instead, with facts such as `address` in `attributes`. | For the United Kingdom, pass `gl=gb` (not `uk`), for example `q=lutron+london&gl=gb&hl=en&domain=google.co.uk`. ## Endpoint Index | Endpoint | Description | | - | - | | `GET /v1/google/search` | Web search with 21 parameters | | `GET /v1/google/images/search` | Image search with size/color filters | | `GET /v1/google/videos/search` | Video search | | `GET /v1/google/autocomplete` | Query suggestions | | `GET /v1/google/ai-mode/search` | AI-generated answers | | `GET /v1/google/lens/search` | Visual image search | | Endpoint | Description | | - | - | | `GET /v1/google/maps/search` | Search places by query | | `GET /v1/google/maps/place` | Place details by `place_id` / `data_id` | | `GET /v1/google/maps/reviews` | Paginated reviews for a place | | `GET /v1/google/maps/photos` | Place photos | | `GET /v1/google/maps/posts` | Business posts | | Endpoint | Description | | - | - | | `GET /v1/google/shopping/search` | Product search with filters + ads | | `GET /v1/google/shopping/product` | Product detail with seller list | | `GET /v1/google/shopping/product/click` | Resolve merchant URL per product (lightweight HTTP lookup) | | Endpoint | Description | | - | - | | `GET /v1/google/news/search` | News article search | | `GET /v1/google/news/topics` | News by predefined topic | | `GET /v1/google/news/trending` | Trending stories | | `GET /v1/google/scholar/search` | Academic paper search | | `GET /v1/google/patents/search` | Patent document search | | `GET /v1/google/patents/detail` | Full patent detail | | Endpoint | Description | | - | - | | `GET /v1/google/hotels/search` | Hotel search w/ dates (modes: `ds0` default richest, `rpc`, `fast`, `render` fallback) | | `GET /v1/google/hotels/details` | Detailed property info | | `GET /v1/google/trends/search` | Unified Trends — `data_type` picks TIMESERIES, GEO\_MAP, GEO\_MAP\_0, RELATED\_TOPICS, or RELATED\_QUERIES | | `GET /v1/google/trends/trending-now` | Current trending searches (search\_volume + deltas) | | `GET /v1/google/trends/autocomplete` | Knowledge Graph topic autocomplete | | `GET /v1/google/jobs/search` | Job listings search | | `GET /v1/google/finance/quote` | Stock / index / crypto quote | | `GET /v1/google/products/detail` | Immersive product detail | ## Credit Costs Per-endpoint credit pricing is configured by ScrapeBadger admins and returned live from `GET https://scrapebadger.com/api/public/pricing` (uncached, updates immediately). The public pricing page and each product landing page at [scrapebadger.com](https://scrapebadger.com) show the authoritative current rate. See [Credits & Pricing](/credits-and-pricing) for plan-level rates. Query `GET /api/public/pricing` in your integration to cache the current per-endpoint cost — don't hardcode credit numbers, they can be adjusted. ## Response Caching Every Google endpoint keeps a shared **5-minute** result cache. A request with the same endpoint and the same query parameters (`q`, `gl`, `hl`, `location`, `num`, `start`, …) as a recent successful request is answered from the cache instead of fetching Google again. Your API key is not part of the cache key, whether you send it as a header or a query parameter. * **Cached responses are free.** They cost **0 credits** and return `X-Credits-Used: 0`. * **Identical requests sent at the same time are merged.** If you send the same request again while the first is still running, the second one waits for the first and receives the same response (also free). * **Only successful responses with data are cached.** Errors, `503 Service Unavailable`, and empty results are never cached, so a retry always makes a fresh attempt. Every response tells you how it was served: | Header | Meaning | | - | - | | `X-Cache` | `MISS` — fetched fresh from Google. `HIT` — served from the cache. `COALESCED` — merged with an identical request that was already running. | | `X-Cache-TTL-Remaining` | Seconds until the cached response expires (only on `HIT` / `COALESCED`). | | `Age` | Seconds since the response was fetched from Google (only on `HIT` / `COALESCED`). | ```bash theme={null} curl -i "https://scrapebadger.com/v1/google/ai-mode/search?q=what+is+scrapebadger" \ -H "X-API-Key: YOUR_API_KEY" # second identical call within 5 minutes: # X-Cache: HIT # X-Cache-TTL-Remaining: 287 # Age: 13 # X-Credits-Used: 0 ``` To force a fresh result, change any query parameter — a different query string is a different cache entry. ## Legal & Compliance **SearchGuard litigation is active.** Google sued SerpAPI in **December 2025** under the DMCA for circumventing the SearchGuard JavaScript challenge it deployed in January 2025. Reddit also sued SerpAPI, Perplexity, and several other scraping providers in October 2025 over crawling its content. Both cases are still being litigated as of 2026 and the legal landscape around SERP scraping is evolving quickly. Before deploying ScrapeBadger Google endpoints in production, you are responsible for: * Reviewing **Google's Terms of Service** and any applicable local laws (DMCA, CFAA in the US; copyright directives in the EU) * Ensuring your use case has a **legitimate business purpose** (research, SEO monitoring, price comparison, accessibility tooling, etc.) and isn't redistributing Google content in a way that competes with Google itself * Following **robots.txt** spirit where applicable and rate-limiting your requests to avoid disrupting Google's services * Consulting your own legal counsel — ScrapeBadger does not provide legal advice and cannot warrant the lawfulness of your specific use case ScrapeBadger reserves the right to suspend access to the Google Scraper endpoints at any time in response to changes in the legal landscape or platform terms. ### Reference cases * *Google LLC v. SerpAPI* (Dec 2025) — DMCA §1201 claim alleging circumvention of SearchGuard * *Reddit v. Perplexity, SerpAPI et al.* (Oct 2025) — breach of access terms and unauthorized data ingestion ScrapeBadger continues to operate under the position that scraping publicly accessible search results for legitimate business research is permitted, but this position may need to evolve as litigation progresses. *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Google. "Google," "Google Maps," "Google Trends," and other Google product names are trademarks of Google LLC, used here only to describe the platforms this scraper is designed to work with.* # Shopping Merchant URL Enrichment Source: https://docs.scrapebadger.com/google/shopping-click-enrichment Resolve the real merchant URL for a Google Shopping product on demand. # Shopping Merchant URL Enrichment Google has removed direct merchant links from organic Shopping HTML — every click in the real Shopping UI now routes through a JavaScript handler. The `/v1/google/shopping/product/click` endpoint materializes the direct merchant URL for any product title on demand. ## How It Works 1. Call `/v1/google/shopping/search?q=laptop` — you get product listings with title, price, source merchant, rating, thumbnail, and a per-product `click_link`. 2. Call the product's `click_link` (or construct `/v1/google/shopping/product/click?title=...&source=...`) — the endpoint uses Google's "I'm Feeling Lucky" redirect (`btnI=1`), scoped to the card's `source` merchant via a `site:` operator, to return the direct product page URL. The `source`-scoped `site:` query guarantees the resolved URL matches the exact merchant whose price was shown in the card, not a generic top organic match. ## Two-Step Example ```javascript Node.js theme={null} import { ScrapeBadger } from "scrapebadger"; const client = new ScrapeBadger({ apiKey: "YOUR_API_KEY" }); // Step 1: search shopping const products = await client.google.shopping.search({ q: "laptop" }); const first = products.results[0]; console.log(first.title, first.price.extracted, first.source); // "Lenovo IdeaPad 5 16IRU9 16\" 2-in-1 Laptop" "$599.00" "Walmart" // Step 2: resolve the merchant URL const enriched = await client.google.shopping.click({ title: first.title, source: first.source, }); console.log(enriched.merchant_url); // "https://www.walmart.com/ip/Lenovo-IdeaPad-5-..." ``` ```python Python theme={null} from scrapebadger import ScrapeBadger async with ScrapeBadger(api_key="YOUR_API_KEY") as client: # Step 1: search shopping products = await client.google.shopping.search("laptop") first = products["results"][0] print(first["title"], first["price"]["extracted"], first["source"]) # Step 2: resolve the merchant URL enriched = await client.google.shopping.click( title=first["title"], source=first["source"], ) print(enriched["merchant_url"]) ``` ```bash cURL theme={null} # Step 1 curl "https://scrapebadger.com/v1/google/shopping/search?q=laptop" \ -H "x-api-key: YOUR_API_KEY" # Step 2 — use the click_link returned in the first response curl "https://scrapebadger.com/v1/google/shopping/product/click?title=Lenovo+IdeaPad+5+16IRU9+16%22+2-in-1+Laptop&source=Walmart&gl=us&hl=en" \ -H "x-api-key: YOUR_API_KEY" ``` ## Response Shape ```json theme={null} { "product_id": "60c2e6fdb6b3", "title": "Lenovo IdeaPad 5 16IRU9 16\" 2-in-1 Laptop Computer", "merchant_url": "https://www.walmart.com/ip/Lenovo-IdeaPad-5-16IRU9-16-2-in-1-Laptop/12345", "merchant_domain": "www.walmart.com", "source_query": "Lenovo IdeaPad 5 16IRU9 16\" 2-in-1 Laptop Computer site:walmart.com" } ``` | Field | Description | | | - | - | - | | `product_id` | Stable MD5 hash of `(title, source, price)` — echoed back so you can correlate with the original search result. | | | `title` | The product title you passed in. | | | `merchant_url` | The direct merchant product page URL, or `null` if no redirect was produced. | | | `merchant_domain` | The host portion of `merchant_url`. | | | `source_query` | The query that was passed to Google's "I'm Feeling Lucky" redirect — useful for debugging. | ## Supported Merchants The endpoint maps common source names to canonical domains for accurate `site:` scoping. Supported out of the box: - **Marketplaces**: Walmart, Best Buy, Amazon (incl. "Amazon.com - Seller"), Target, eBay, Newegg, Costco, Home Depot, Lowe's, Staples, Office Depot, Micro Center, Adorama, B\&H Photo-Video-Pro Audio | * **Brand stores**: HP, Dell, Lenovo, Apple, Razer, Asus, Acer, HyperX, MSI, Samsung For sources not in the map, the endpoint falls back to a bare-title query (no `site:` scope) which still resolves a valid merchant URL — just not necessarily the one whose price was shown. ## Pricing The endpoint uses a lightweight HTTP request, not a browser. Per-call credit cost is configured in the admin panel and returned live from `GET /public/pricing` — query that endpoint for the authoritative current rate. ## Why This Exists Google's organic Shopping HTML doesn't contain merchant URLs at all — clicking a product card opens a JavaScript modal that fetches merchant info only when you actually click "Visit site". Attempting to capture that flow in a single synchronous scrape is impractical (\~60-90s per query for 50 products). Instead, the ScrapeBadger Shopping click endpoint exposes merchant URL resolution as a **per-product on-demand call** — you only pay for enrichment when you actually need the link. # Shopping Offers by Barcode or Catalog ID Source: https://docs.scrapebadger.com/google/shopping-offers Get multi-seller Google Shopping prices for a product looked up by its barcode (GTIN/UPC/EAN) or by its Google Shopping catalog ID. # Shopping Offers by Barcode or Catalog ID `/v1/google/shopping/offers` returns a product's Google Shopping **seller offers** — one entry per merchant `source`, each with its own `price` and merchant `link`. Identify the product one of two ways (exactly one is required): * **`barcode`** — Google Shopping no longer matches raw GTIN/UPC/EAN codes, so the barcode is first **resolved to a product** via a Google web search, then the Shopping seller list is fetched. * **`catalog_id`** — Google's own Shopping catalog identifier: what a Google Shopping product URL carries as `prds=catalogid:`, and the `catalog_id` field on [Shopping Search](/google/shopping-search) tiles when Google exposes it there (for example `https://www.google.com/search?ibp=oshop&prds=catalogid:762120719996356571&gl=de&hl=de`). The seller list is read straight off Google's product page, every page of sellers fetched in parallel, so there is no resolve hop and no ambiguity about which product you get. ## Offers by Catalog ID ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google/shopping/offers?catalog_id=762120719996356571&gl=de&hl=de" \ -H "x-api-key: YOUR_API_KEY" ``` ```python Python theme={null} from scrapebadger import ScrapeBadger async with ScrapeBadger(api_key="YOUR_API_KEY") as client: result = await client.google.shopping.offers(catalog_id="762120719996356571", gl="de", hl="de") print(result["product_title"], result["total_offers"]) for offer in result["offers"]: print(offer["source"], offer["price"]["extracted"], offer["link"]) ``` ```javascript Node.js theme={null} const result = await client.google.shopping.offers({ catalog_id: "762120719996356571", gl: "de", hl: "de", }); console.log(result.product_title, result.total_offers); ``` ```json theme={null} { "catalog_id": "762120719996356571", "total_offers": 19, "product_title": "Fehn Mini-Spieluhr Schaf", "offers": [ { "position": 1, "title": "Fehn Spieluhr Schaf Baby Love 18 cm natur", "source": "babymarkt.com de", "price": { "value": 12.6, "currency": "EUR", "extracted": "12,60 €" }, "extracted_price": 12.6, "link": "https://www.babymarkt.com/de/p/fehn-spieluhr-schaf-baby-love-18-cm-105648/?variant=105648", "delivery": "Lieferung: 4,99 €", "extensions": ["Online auf Lager", "Lieferung: 4,99 €", "Rücknahme innerhalb von 14 Tagen"] } ] } ``` `total_offers` is the number of sellers Google lists for the catalog entry; up to 60 are returned. The most reliable way to get a `catalog_id` is from a Google Shopping product URL (`prds=catalogid:`). Shopping Search tiles carry it as `catalog_id` only when Google ships the identifier block on that SERP, so treat that field as optional. ## How Barcode Lookup Works 1. The barcode is validated (length + check digit). GTIN-8, UPC-A, EAN-13, and GTIN-14 are accepted. 2. A Google **web search** resolves the barcode to a product (the matched product name is returned as `resolved_query` / `product_title`). 3. A Google **Shopping** fetch for that product returns the per-merchant offers. Because this performs **two Google fetches**, each call costs **14 credits**. ## Query Parameters Product barcode to look up. Accepts GTIN-8, UPC-A (12 digits), EAN-13, or GTIN-14. The check digit is validated — a malformed or checksum-failing barcode returns `422`. Exactly one of `barcode` / `catalog_id` is required. Example: `0711719541028` Google Shopping catalog ID — `prds=catalogid:` in a Google Shopping product URL (or the `catalog_id` on a Shopping Search tile when present). Exactly one of `barcode` / `catalog_id` is required. Example: `762120719996356571` Country to run the search and Shopping fetch in, as an ISO-3166 alpha-2 code. Controls which merchants and currency you see. Examples: `us`, `au`, `gb`, `de` Language code for the search and results. Examples: `en`, `de`, `fr` ## Example ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google/shopping/offers?barcode=0711719541028" \ -H "x-api-key: YOUR_API_KEY" ``` ```python Python theme={null} from scrapebadger import ScrapeBadger async with ScrapeBadger(api_key="YOUR_API_KEY") as client: result = await client.google.shopping.offers(barcode="0711719541028", gl="us") print(result["product_title"]) # "Sony PlayStation 5 Console" for offer in result["offers"]: print(offer["source"], offer["price"]["extracted"]) ``` ```javascript Node.js theme={null} import { ScrapeBadger } from "scrapebadger"; const client = new ScrapeBadger({ apiKey: "YOUR_API_KEY" }); const result = await client.google.shopping.offers({ barcode: "0711719541028", gl: "us" }); console.log(result.product_title); // "Sony PlayStation 5 Console" for (const offer of result.offers) { console.log(offer.source, offer.price.extracted); } ``` Pass `gl` to scope to a regional marketplace — for example, an Australian Woolworths grocery barcode: ```bash cURL theme={null} curl "https://scrapebadger.com/v1/google/shopping/offers?barcode=9300633572457&gl=au" \ -H "x-api-key: YOUR_API_KEY" ``` ```python Python theme={null} from scrapebadger import ScrapeBadger async with ScrapeBadger(api_key="YOUR_API_KEY") as client: result = await client.google.shopping.offers(barcode="9300633572457", gl="au") ``` ```javascript Node.js theme={null} const result = await client.google.shopping.offers({ barcode: "9300633572457", gl: "au", }); ``` ## Response Shape ```json theme={null} { "barcode": "0711719541028", "resolved_query": "Sony PlayStation 5 Console", "product_title": "Sony PlayStation 5 Console", "offers": [ { "title": "PlayStation 5 Console (Slim)", "source": "Walmart", "price": { "value": 499.0, "currency": "USD", "extracted": "$499.00" }, "link": "https://www.walmart.com/ip/PlayStation-5-Console/...", "rating": 4.8 }, { "title": "Sony PlayStation 5 Slim Disc Console", "source": "Best Buy", "price": { "value": 499.99, "currency": "USD", "extracted": "$499.99" }, "link": "https://www.bestbuy.com/site/...", "rating": 4.7 } ] } ``` | Field | Description | | - | - | | `barcode` | The barcode you passed in, echoed back (barcode mode). | | `catalog_id` | The catalog ID you passed in (catalog mode). | | `total_offers` | Total sellers Google lists for the catalog entry (catalog mode). | | `resolved_query` | The product query the barcode resolved to via Google web search. | | `product_title` | The matched product's title. | | `offers` | List of per-merchant Shopping offers. | | `offers[].title` | The product title as listed by that merchant. | | `offers[].source` | The merchant / seller name (e.g. `Walmart`, `Best Buy`). | | `offers[].price.value` | Numeric price. | | `offers[].price.currency` | ISO currency code. | | `offers[].price.extracted` | The price as displayed, including symbol. | | `offers[].link` | Link to the merchant's listing. | | `offers[].delivery` | Shipping line as Google shows it (catalog mode). | | `offers[].extensions` | Availability / shipping / returns lines (catalog mode). | | `offers[].rating` | Product rating on that merchant, if shown. | ## Pricing Each call costs **14 credits**, whichever identifier you pass. ## Errors | Status | Meaning | | - | - | | `400` | Neither or both of `barcode` / `catalog_id` were passed. | | `422` | The `barcode` is malformed or fails its check-digit validation. | | `404` | The barcode could not be resolved to a product (no Google web-search match), or the catalog ID has no sellers. | ## Why This Exists Google Shopping indexes by product, not by barcode — a GTIN/UPC/EAN typed directly into Shopping yields no matches. Resolving the barcode through a normal Google web search first finds the product page, and only then does a Shopping fetch return the seller offers. This endpoint packages that two-step flow into a single call so you can go straight from a barcode to live multi-seller prices. # Immobiliare.it Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/immobiliare/overview Scrape Immobiliare Group real-estate listings, full property detail, agency profiles, and €/m² price insights across Italy, Spain, Greece, and Luxembourg with structured JSON responses. ## Scraper API for Immobiliare.it Search listings, pull full property detail, fetch agency profiles and their active inventory, and read €/m² price-history insights from **Immobiliare.it** — Italy's #1 real-estate portal — and the whole **Immobiliare Group**. One API covers four portals that share the same platform: Italy (`immobiliare.it`), Spain (`indomio.es`), Greece (`indomio.gr`), and Luxembourg (`immotop.lu`). ScrapeBadger handles authentication, rotating proxies, anti-bot evasion, and parsing automatically — no upstream API key required. ## Key Features Italy, Spain, Greece, and Luxembourg through a single `market` parameter — same endpoints, filters, and response models across all four portals. Free-text [`location`](/api-reference/endpoint/immobiliare/search) or precise `region_id` / `province_id` / `city_id`, with `sale` / `rent` contracts, categories, and price, surface, rooms, and bathroom filters. Price + €/m² + loan estimate, surface, rooms, floor, energy class, condo fees, GPS, every photo in three sizes, and a per-unit `properties[]` breakdown. Agency profiles with address, GPS, phone numbers, opening hours, ads / sales counts, and the full agent roster — plus the agency's active listings. Monthly €/m² time series per region, province, or city — for sale or rent — the same market data behind Immobiliare's price pages. First-class support via the ScrapeBadger Node.js and Python SDKs. All four portals (`immobiliare.it`, `indomio.es`, `indomio.gr`, `immotop.lu`) run on one shared platform. Every endpoint, filter, and response model behaves identically across markets — only the inventory, language, and geography ids differ. Switch markets with the `market` parameter. ## Coverage & Markets | Code | Country | Portal | Locale | Currency | | - | - | - | - | - | | `it` | 🇮🇹 Italy | [www.immobiliare.it](http://www.immobiliare.it) | it | EUR | | `es` | 🇪🇸 Spain | [www.indomio.es](http://www.indomio.es) | es | EUR | | `gr` | 🇬🇷 Greece | [www.indomio.gr](http://www.indomio.gr) | el | EUR | | `lu` | 🇱🇺 Luxembourg | [www.immotop.lu](http://www.immotop.lu) | fr | EUR | Start from [`/autocomplete`](/api-reference/endpoint/immobiliare/autocomplete) to turn a free-text place (e.g. `Milano`) into precise `region_id` / `province_id` / `city_id` values, feed them to [`/search`](/api-reference/endpoint/immobiliare/search), then reuse the same ids on [`/market-insights/prices`](/api-reference/endpoint/immobiliare/price-insights) for that area's €/m² history. ## Quick Start ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/immobiliare/search?" + new URLSearchParams({ location: "Milano", contract: "sale", category: "residential", price_max: "300000", rooms_min: "3", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); console.log(data.count, "of", data.total_ads, "listings"); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/immobiliare/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "location": "Milano", "contract": "sale", "category": "residential", "price_max": 300000, "rooms_min": 3, }, ) data = res.json() print(data["count"], "of", data["total_ads"], "listings") ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/immobiliare/search?location=Milano&contract=sale&category=residential&price_max=300000&rooms_min=3" \ -H "X-API-Key: YOUR_API_KEY" ``` ## Endpoints | Endpoint | Method | Description | | - | - | - | | [`/v1/immobiliare/search`](/api-reference/endpoint/immobiliare/search) | GET | Search listings (sale / rent) | | [`/v1/immobiliare/listings/{id}`](/api-reference/endpoint/immobiliare/get-listing) | GET | Full detail for a single listing | | [`/v1/immobiliare/agencies/{id}`](/api-reference/endpoint/immobiliare/get-agency) | GET | Agency profile | | [`/v1/immobiliare/agencies/{id}/listings`](/api-reference/endpoint/immobiliare/get-agency-listings) | GET | An agency's active listings | | [`/v1/immobiliare/market-insights/prices`](/api-reference/endpoint/immobiliare/price-insights) | GET | Monthly €/m² price time series | | [`/v1/immobiliare/autocomplete`](/api-reference/endpoint/immobiliare/autocomplete) | GET | Resolve a place into geography ids | | [`/v1/immobiliare/markets`](/api-reference/endpoint/immobiliare/list-markets) | GET | List supported markets | ## Credit Costs | Endpoint | Cost | | - | - | | Search | 5 credits | | Get listing detail | 10 credits | | Get agency profile | 5 credits | | Get agency listings | 5 credits | | Price insights | 10 credits | | Autocomplete | 2 credits | | List markets | 0 credits | | Failed requests | 0 credits | ## Authentication All requests require your API key in the `X-API-Key` header: ```bash theme={null} curl "https://scrapebadger.com/v1/immobiliare/search?location=Milano" \ -H "X-API-Key: YOUR_API_KEY" ``` Credits are charged per request (see the table above) and reported on the `X-Credits-Used` response header. ## Anti-Bot & Proxies Immobiliare Group portals protect their catalog with IP-reputation scoring and TLS/HTTP fingerprinting. ScrapeBadger clears these automatically using rotating proxies and browser fingerprint rotation on market-appropriate sessions. You never manage proxies, sessions, or CAPTCHAs, and you never need an upstream API key. ## Next Steps Full API reference for searching Immobiliare Group listings Retrieve a listing's complete detail by its numeric id *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Immobiliare.it. "Immobiliare.it" is a trademark of Immobiliare.it S.p.A., used here only to describe the platform this scraper is designed to work with.* # Introduction Source: https://docs.scrapebadger.com/index Scrape any website and access Twitter/X data through a simple REST API. Web scraping with anti-bot bypass, AI extraction, and 50+ Twitter endpoints. ## What is ScrapeBadger? ScrapeBadger is a unified web scraping and data API. Scrape any website with automatic anti-bot bypass, JavaScript rendering, and AI-powered data extraction — or access Twitter/X data through 50+ structured endpoints. No infrastructure to manage. **Base URL:** `https://scrapebadger.com/v1` ```bash Web Scraping theme={null} curl -X POST "https://scrapebadger.com/v1/web/scrape" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://scrapebadger.com", "format": "markdown"}' ``` ```bash Twitter API theme={null} curl -X GET "https://scrapebadger.com/v1/twitter/users/elonmusk/by_username" \ -H "x-api-key: YOUR_API_KEY" ``` ## Key Features Scrape any website with smart engine selection, anti-bot bypass, and AI extraction. Tweets, users, lists, communities, trends, geo data, and Twitter Spaces. Automatic proxy rotation, retry logic, and rate limit management handled for you. ## Quick Links Get up and running in 5 minutes with your first API call. Scrape any website with anti-bot bypass and AI extraction. Browse all endpoints with examples and response schemas. Understand the credit-based pricing model. # Instagram Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/instagram/overview Pull public Instagram data — profiles, posts, media detail and comments — as clean JSON, with no Instagram login or API key required. ## Scraper API for Instagram The ScrapeBadger **Instagram API** turns `instagram.com`'s public surface into a clean JSON feed: user profiles and their `posts`, media detail by shortcode, and paginated `comments`. Every other Instagram endpoint needs the **authenticated (account-pool) tier**, which is **temporarily unavailable** while we scale the pool: related profiles, user about/videos/reels/tagged/pinned, followers/following, stories/highlights, media `oembed`, media and comment likers, comment replies, all hashtag endpoints (info, `top`, `recent`, `reels`), all locations, audio, and all search variants (`hashtags`, `top`, users/places/reels/music/autocomplete). They currently return `503 {"error": "temporarily_unavailable"}` with a `Retry-After` header and are **not billed**. The [hashtag](/api-reference/endpoint/instagram/get-hashtag) and [search](/api-reference/endpoint/instagram/search) pages stay published, flagged, so the request shape is known when they return. All endpoints are `GET`, live under `https://scrapebadger.com/v1/instagram/*`, and authenticate with the `X-API-Key` header. **No Instagram account or upstream API key is required** — ScrapeBadger handles authentication, rate limiting, TLS fingerprinting and proxy rotation transparently. Credits are charged per request (see the table below) and reported on the `X-Credits-Used` response header. ## Features * **Profiles** — full public profile by `username`: bio, links, counts, verification, business/professional metadata, plus paginated `posts`. * **Media** — media detail by shortcode `code` and paginated `comments`. * **Hashtags & search** — temporarily unavailable (see above). ## Honesty caveat These endpoints read Instagram's **public** surface only. Private accounts expose profile metadata but not their posts or media. Fields reflect what Instagram serves to an unauthenticated client; some professional/business fields are only present when the account has opted into them. ## Conventions * **Pagination.** List endpoints take `amount` (page size) and a `cursor` (opaque next-page token). Every list response is wrapped in `{ items, count, next_cursor, has_more }` — pass `next_cursor` back as `cursor` to walk forward until `has_more` is `false`. * **Datetimes.** Every datetime ships in **both** a Unix form (`*_utc`) and an ISO 8601 UTC string (`*_at`), e.g. `taken_at` + `taken_at_utc`. ## Credits | Endpoint group | Example path | Credits | | - | - | - | | Health / reference | `GET /v1/instagram/health` | 0 | | Standard read | `GET /v1/instagram/users/{username}` | 5 | | Paginated listings | `GET /v1/instagram/users/{username}/posts` | 8 | Standard read (5) covers profile and media detail. Paginated listings (8) cover `posts` and `comments`. A `503 temporarily_unavailable` from a gated endpoint costs 0 credits. ## Quickstart ```bash cURL theme={null} curl "https://scrapebadger.com/v1/instagram/users/instagram" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/instagram/users/instagram", { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const { user } = await res.json(); console.log(user.follower_count, "followers"); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/instagram/users/instagram", headers={"X-API-Key": "YOUR_API_KEY"}, ) print(res.json()["user"]["follower_count"], "followers") ``` Resolve a handle with [`/users/{username}`](/api-reference/endpoint/instagram/get-user), then page their media with [`/users/{username}/posts`](/api-reference/endpoint/instagram/user-posts) by passing the returned `next_cursor` back as `cursor` until `has_more` is false. *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Instagram or Meta. "Instagram" is a trademark of Meta Platforms, Inc., used here only to describe the platform this scraper is designed to work with.* # Leboncoin Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/leboncoin/overview Scrape Leboncoin classified ads, ad details, sellers, and storefronts across France with region, department, and city filters and structured JSON responses. ## Scraper API for Leboncoin Search classified ads, pull full ad detail, fetch similar ads, and retrieve seller profiles and storefronts from **Leboncoin** — France's largest classifieds marketplace. The API handles authentication, DataDome anti-bot bypass, and French location routing automatically. ## Key Features Full national coverage of leboncoin.fr, filterable by region, department, city, or postal code. Narrow searches by [`region_id`](/api-reference/endpoint/leboncoin/list-regions), [`department_id`](/api-reference/endpoint/leboncoin/list-departments), `city`, or `zipcode`, including DOM-TOM overseas territories. Automatic session management, Chrome TLS impersonation, and fingerprint rotation to clear Leboncoin's DataDome protection. Prices, category-specific attributes, images, publication dates, shipping eligibility, and seller info. Private and pro seller profiles, feedback scores, store ratings, reviews, and full storefront listings. Requests are routed through French proxies for accurate pricing, availability, and DataDome trust. First-class support via the ScrapeBadger Node.js and Python SDKs. Leboncoin is a **single-country marketplace** (France only). There is no `domain` or `market` selector — instead you scope results geographically with `region_id`, `department_id`, `city`, or `zipcode`. Overseas territories (DOM-TOM) are exposed as region values. ## Coverage & Locations Leboncoin operates as one national marketplace (`leboncoin.fr`). Instead of picking a country domain, you filter results by French administrative geography: | Filter | Parameter | Lookup endpoint | | - | - | - | | Region (incl. DOM-TOM) | `region_id` | [`/v1/leboncoin/regions`](/api-reference/endpoint/leboncoin/list-regions) | | Department | `department_id` | [`/v1/leboncoin/departments`](/api-reference/endpoint/leboncoin/list-departments) | | City / postal code | `city`, `zipcode` | [`/v1/leboncoin/locations/search`](/api-reference/endpoint/leboncoin/search-locations) | Use [`/v1/leboncoin/locations/search`](/api-reference/endpoint/leboncoin/search-locations) to resolve a free-text place name (e.g. `Lyon`) into a structured location with its `region_id`, `department_id`, and coordinates. Use [`/v1/leboncoin/markets`](/api-reference/endpoint/leboncoin/list-markets) to get the market metadata (currency, locale) programmatically. ## Quick Start ```javascript Node.js theme={null} import ScrapeBadger from "scrapebadger"; const client = new ScrapeBadger({ apiKey: "YOUR_API_KEY" }); const results = await client.leboncoin.search({ text: "vélo électrique", region_id: "22", page: 1, }); console.log(results.ads); ``` ```python Python theme={null} from scrapebadger import ScrapeBadger client = ScrapeBadger(api_key="YOUR_API_KEY") results = client.leboncoin.search( text="vélo électrique", region_id="22", page=1, ) print(results.ads) ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/leboncoin/search?text=v%C3%A9lo+%C3%A9lectrique®ion_id=22&page=1" \ -H "x-api-key: YOUR_API_KEY" ``` ## Endpoints | Endpoint | Method | Description | | - | - | - | | [`/v1/leboncoin/search`](/api-reference/endpoint/leboncoin/search-ads) | GET | Search ads across France | | [`/v1/leboncoin/ads/{list_id}`](/api-reference/endpoint/leboncoin/get-ad) | GET | Full detail for a single ad | | [`/v1/leboncoin/ads/{list_id}/similar`](/api-reference/endpoint/leboncoin/get-similar-ads) | GET | Ads similar to a given ad | | [`/v1/leboncoin/sellers/{user_id}`](/api-reference/endpoint/leboncoin/get-seller) | GET | Seller public profile | | [`/v1/leboncoin/sellers/{user_id}/listings`](/api-reference/endpoint/leboncoin/get-seller-listings) | GET | A seller's active listings | | [`/v1/leboncoin/categories`](/api-reference/endpoint/leboncoin/list-categories) | GET | List categories | | [`/v1/leboncoin/regions`](/api-reference/endpoint/leboncoin/list-regions) | GET | List French regions (incl. DOM-TOM) | | [`/v1/leboncoin/departments`](/api-reference/endpoint/leboncoin/list-departments) | GET | List departments | | [`/v1/leboncoin/locations/search`](/api-reference/endpoint/leboncoin/search-locations) | GET | Autocomplete a location by name | | [`/v1/leboncoin/markets`](/api-reference/endpoint/leboncoin/list-markets) | GET | List supported markets | ## Credit Costs | Endpoint | Cost | | - | - | | Search | 5 credits | | Get ad detail | 5 credits | | Get similar ads | 5 credits | | Get seller | 5 credits | | Seller listings | 5 credits | | Search locations | 2 credits | | List categories | 0 credits | | List regions | 0 credits | | List departments | 0 credits | | List markets | 0 credits | | Failed requests | 0 credits | ## Authentication All requests require your API key in the `X-API-Key` header: ```bash theme={null} curl "https://scrapebadger.com/v1/leboncoin/search?text=iphone" \ -H "X-API-Key: YOUR_API_KEY" ``` ## Anti-Bot Handling Leboncoin protects its catalog with **DataDome**, which combines IP-reputation scoring, TLS/HTTP-2 fingerprinting, and JavaScript challenges. ScrapeBadger clears these automatically using Chrome TLS impersonation on French sessions. You never need to manage proxies, sessions, or CAPTCHAs. For accurate pricing, availability, and DataDome trust, requests are routed through French proxies. This is handled automatically. ## Next Steps Full API reference for searching Leboncoin classifieds Retrieve the full detail for a single ad by `list_id` *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by leboncoin. "leboncoin" is a trademark of LBC France SAS (part of the Adevinta group), used here only to describe the platform this scraper is designed to work with.* # LinkedIn Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/linkedin/overview Pull public LinkedIn data — job listings, companies, schools, profiles, posts and courses — as clean JSON, with no LinkedIn login or API key required. ## Scraper API for LinkedIn The ScrapeBadger **LinkedIn API** turns `linkedin.com`'s public, logged-out surface into a clean JSON feed: job search and job detail, company and school pages, public member profiles, posts and Pulse articles, LinkedIn Learning courses, and a geo/company typeahead for resolving filter ids. All endpoints are `GET`, live under `https://scrapebadger.com/v1/linkedin/*`, and authenticate with the `X-API-Key` header. Credits are charged per request (see the table below) and reported on the `X-Credits-Used` response header. Every endpoint accepts an optional `country` param (default `us`). ## Features * **Job search** — keyword + location search over LinkedIn's public jobs guest API, with filters for date posted, experience level, job type, workplace (onsite/remote/hybrid), company and sort order. Paginates in blocks of 25 via `start`. * **Job detail** — full description (HTML + text), salary, seniority, employment type, job functions, industries, applicant counts and the apply URL, by numeric `job_id`. * **Company jobs** — every public opening for a company, by numeric `company_id`. * **Company & school pages** — the public company / university page: about, website, industry, size, headquarters, specialties, follower and employee counts, by `universal_name` slug. * **Member profiles** — a public member's logged-out profile: headline, location, about, experience, education, languages and awards, by vanity `public_id`. * **Posts & articles** — a public post or Pulse article with author, body, reactions and top-level comments. * **LinkedIn Learning** — a course's title, description, provider, workload, rating and instructors. * **Geo / company typeahead** — resolve a free-text place or company name to the numeric `geo_id` / `company_id` the job-search filters expect. ## Honesty caveat These endpoints read LinkedIn's **public, logged-out** surface only. A member profile is the JSON-LD subset LinkedIn exposes to signed-out visitors — **not** the full logged-in record: no contact info, no connection graph, and only the coarse skills/experience LinkedIn chooses to render publicly. **People search, employee search and full skill lists are out of scope** — they are auth-gated and not available here. ## Coverage | Code | Country | Locale | Domain | | - | - | - | - | | `us` | United States | en-US | linkedin.com | `country` (default `us`) sets the locale LinkedIn renders for jobs and place resolution. All data is drawn from the global `linkedin.com` domain. ## Credits | Endpoint | Path | Credits | | - | - | - | | Search jobs | `GET /v1/linkedin/jobs/search` | 5 | | Get job | `GET /v1/linkedin/jobs/{job_id}` | 5 | | Company jobs | `GET /v1/linkedin/companies/{company_id}/jobs` | 5 | | Get company | `GET /v1/linkedin/companies/{universal_name}` | 6 | | Get school | `GET /v1/linkedin/schools/{universal_name}` | 6 | | Get profile | `GET /v1/linkedin/profiles/{public_id}` | 8 | | Get post | `GET /v1/linkedin/posts/{post_slug}` | 5 | | Get article | `GET /v1/linkedin/articles/{article_slug}` | 5 | | Get course | `GET /v1/linkedin/learning/{course_slug}` | 5 | | Geo / company suggest | `GET /v1/linkedin/geo/suggest` | 2 | ## Quickstart ```bash cURL theme={null} curl "https://scrapebadger.com/v1/linkedin/jobs/search?keywords=software%20engineer&location=New%20York" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/linkedin/jobs/search?" + new URLSearchParams({ keywords: "software engineer", location: "New York", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); console.log(data.jobs.length, "jobs"); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/linkedin/jobs/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={"keywords": "software engineer", "location": "New York"}, ) print(len(res.json()["jobs"]), "jobs") ``` Start from [`/geo/suggest`](/api-reference/endpoint/linkedin/geo-suggest) to turn a free-text place or company name into the numeric `geo_id` / `company_id` that [`/jobs/search`](/api-reference/endpoint/linkedin/search-jobs) filters on, then page results in blocks of 25 with `start`. *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by LinkedIn. "LinkedIn" is a trademark of LinkedIn Corporation (a Microsoft company), used here only to describe the platform this scraper is designed to work with.* # LoopNet Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/loopnet/overview Scrape LoopNet commercial real estate across 5 markets (US, CA, UK, FR, ES) — for-lease, for-sale, and auction listings with full detail, spaces, broker contacts, and media — as structured JSON. ## Scraper API for LoopNet Search **for-lease**, **for-sale**, and **auction** commercial listings, pull **full listing detail** (rent/price with \$/SF, building class and size, spaces, amenities, walk score, photos and 3D tours, the complete facts table), and look up **broker profiles** across **loopnet.com (US)**, **loopnet.ca (CA)**, **loopnet.co.uk (UK)**, **loopnet.fr (FR)**, and **loopnet.es (ES)** — the widest LoopNet commercial-real-estate API. Authentication, anti-bot bypass, and market routing are handled automatically. ## Key Features One API over **loopnet.com**, **loopnet.ca**, **loopnet.co.uk**, **loopnet.fr**, and **loopnet.es**. Pick a market with the `market` parameter. **For-lease**, **for-sale**, and **auction** listings across Office, Retail, Industrial, Multifamily, Land, Hospitality, Healthcare, and more. Rent/price + \$/SF, building class/size/height, year built/renovated, amenities, walk score, zoning, parking, and the full LoopNet facts table. Per-space availability (size, rent, term, floor, condition) plus broker contacts — and full [broker profiles](/api-reference/endpoint/loopnet/get-broker-profile) with their listings. Photo galleries, videos, documents, and **3D virtual tour** flags on every listing. LoopNet sits behind Akamai Bot Manager. ScrapeBadger clears it automatically with real-browser sessions — no proxies or CAPTCHAs to manage. LoopNet caps search results at roughly **500 per query** (about 25 per page, pages `1`-`20`). For dense metros, narrow by `property_type`, price, or size filters to see everything. ## Supported Markets The API covers five national LoopNet portals. Use the `market` query parameter to target one. | Market | Portal | Country | Currency | Locale | | - | - | - | - | - | | :us: `us` | loopnet.com | US | USD | en-US | | :canada: `ca` | loopnet.ca | CA | CAD | en-CA | | :uk: `uk` | loopnet.co.uk | GB | GBP | en-GB | | :fr: `fr` | loopnet.fr | FR | EUR | fr-FR | | :es: `es` | loopnet.es | ES | EUR | es-ES | If no `market` is specified, it defaults to `us`. Use the [`/v1/loopnet/markets`](/api-reference/endpoint/loopnet/list-markets) endpoint to get the full list (with domain, currency, and locale) programmatically. ## Quick Start ```javascript Node.js theme={null} import ScrapeBadger from "scrapebadger"; const client = new ScrapeBadger({ apiKey: "YOUR_API_KEY" }); const results = await client.loopnet.search({ location: "Houston, TX", listingType: "for-sale", propertyType: "office", }); console.log(results.results); ``` ```python Python theme={null} from scrapebadger import ScrapeBadger client = ScrapeBadger(api_key="YOUR_API_KEY") results = client.loopnet.search( location="Houston, TX", listing_type="for-sale", property_type="office", ) print(results.results) ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/loopnet/search?location=Houston,+TX&listing_type=for-sale&property_type=office" \ -H "x-api-key: YOUR_API_KEY" ``` ## Endpoints | Endpoint | Method | Description | | - | - | - | | [`/v1/loopnet/search`](/api-reference/endpoint/loopnet/search-listings) | GET | Search a market for commercial listings | | [`/v1/loopnet/listings/{listing_id}`](/api-reference/endpoint/loopnet/get-listing-detail) | GET | Full detail for a single listing | | [`/v1/loopnet/brokers/{slug}/{broker_id}`](/api-reference/endpoint/loopnet/get-broker-profile) | GET | Broker profile with their listings | | [`/v1/loopnet/markets`](/api-reference/endpoint/loopnet/list-markets) | GET | List all supported markets | | [`/v1/loopnet/property-types`](/api-reference/endpoint/loopnet/list-property-types) | GET | List all property-type filter slugs | ## Credit Costs | Endpoint | Cost | | - | - | | Search | 10 credits | | Get listing detail | 12 credits | | Get broker profile | 8 credits | | List markets | 0 credits | | List property types | 0 credits | | Failed requests | 0 credits | ## Authentication All requests require your API key in the `X-API-Key` header: ```bash theme={null} curl "https://scrapebadger.com/v1/loopnet/search?location=Miami,+FL" \ -H "X-API-Key: YOUR_API_KEY" ``` ## Anti-Bot Handling Every LoopNet portal is protected by Akamai Bot Manager with behavioral scoring and sensor challenges. ScrapeBadger clears these automatically using real Chrome browser sessions routed through proxies in the market's country. You never need to manage proxies, sessions, or CAPTCHAs. Because requests are served through real browsers, LoopNet responses are slower than plain-HTTP scrapers — expect **\~15-20 seconds** per request. ## Rich Datapoints Every listing carries a deep set of structured fields: | Group | Fields | | - | - | | **Pricing** | `price`, `price_text`, `price_currency`, `price_period`, `price_per_sqft`, `rental_rate_text`, `cap_rate`, `noi` | | **Building** | `property_type`, `property_sub_type`, `building_class`, `building_size_sqft`, `building_height`, `ceiling_height`, `year_built`, `year_built_renovated`, `stories`, `units`, `tenancy`, `percent_leased` | | **Lot & Zoning** | `lot_size_acres`, `lot_size_text`, `zoning`, `parcel_id`, `parking`, `walk_score` | | **Location** | `address`, `city`, `state`, `zip`, `county`, `latitude`, `longitude` | | **Media** | `images[]`, `photo_count`, `videos[]`, `documents[]`, `has_virtual_tour` | | **Context** | `spaces[]` (per-unit size/rent/term/floor), `brokers[]` (name, company, phone, email), `amenities[]`, `highlights[]`, `additional_facts[]` (the full LoopNet facts table) | Search returns each result as a `ListingCard`; the [listing detail](/api-reference/endpoint/loopnet/get-listing-detail) endpoint returns a `ListingDetail` that adds spaces, amenities, media, and every fact LoopNet publishes. All datetime fields ship both as Unix timestamps (`*_utc`) and ISO-8601 strings (`*_at`). ## Next Steps Full API reference for searching the LoopNet catalogs Retrieve full detail, spaces, brokers, media, and the facts table for a listing *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by LoopNet or CoStar Group, Inc. "LoopNet" is a trademark of CoStar Group, Inc., used here only to describe the platform this scraper is designed to work with.* # ChatGPT Source: https://docs.scrapebadger.com/mcp/integrations/chatgpt Connect ScrapeBadger to ChatGPT via MCP. # ChatGPT ChatGPT supports MCP through Developer Mode (beta). ## Setup Go to **Settings** > **Apps** > **Advanced settings** > enable **Developer Mode**. Click **Create app** next to Advanced settings. Enter the ScrapeBadger MCP server URL: ``` https://mcp.scrapebadger.com/mcp ``` Choose **OAuth** to sign in with your ScrapeBadger account (no key handling), or select API-key auth and paste your key. ChatGPT MCP is UI-based — there is no config file. Available on Pro, Plus, Business, and Enterprise plans. ## What you can ask Once connected, ChatGPT can call any of ScrapeBadger's 344 tools (Twitter/X, Google, YouTube, TikTok, Amazon, eBay, Reddit, real estate, web scraping) directly. Try: > "Search Google News for openai gpt-5 in the past week and summarize the top 5 articles" > "Find me a 16-inch laptop on Google Shopping under \$1500 and tell me where to buy it" ChatGPT will pick `google_news_search` and `google_shopping_search` + `google_shopping_product_click` automatically. # Claude Code Source: https://docs.scrapebadger.com/mcp/integrations/claude-code Connect ScrapeBadger to Claude Code (CLI) via MCP. # Claude Code Claude Code has native HTTP transport support — no bridge needed. ## Setup Run this command in your terminal: ```bash theme={null} claude mcp add --transport http scrapebadger \ https://mcp.scrapebadger.com/mcp ``` No API key needed — the first time Claude Code connects, your browser opens the ScrapeBadger sign-in and consent screen (OAuth). To use an API key instead, pass it as a header: ```bash theme={null} claude mcp add --transport http scrapebadger \ https://mcp.scrapebadger.com/mcp \ --header "Authorization: Bearer YOUR_API_KEY" ``` Or add to `.mcp.json` in your project root: ```json theme={null} { "mcpServers": { "scrapebadger": { "type": "http", "url": "https://mcp.scrapebadger.com/mcp", "headers": { "Authorization": "Bearer YOUR_API_KEY" } } } } ``` ## Verify Inside a Claude Code session, type `/mcp` to see connected servers. ScrapeBadger should show 344 tools. ## Scopes | Scope | Config Location | Use Case | | - | - | - | | Local (default) | `~/.claude.json` per project | Project-specific | | Project | `.mcp.json` in project root | Shared with team via git | | User | `~/.claude.json` globally | Available everywhere | Add `--scope user` to the `claude mcp add` command for global access. ## Examples Once connected, ask Claude Code natural-language questions and it will pick the right tool: > "Show me the top 5 results on Google for 'rust async runtime' and summarize them" Claude Code calls `google_search`. > "Find me a laptop under \$1500 on Google Shopping and give me the merchant URL for the cheapest one" Claude Code chains `google_shopping_search` → `google_shopping_product_click`. # Claude Desktop Source: https://docs.scrapebadger.com/mcp/integrations/claude-desktop Connect ScrapeBadger to Claude Desktop via MCP. # Claude Desktop ## One-Click Setup (Recommended) Claude Desktop and claude.ai support custom connectors with OAuth — no API key or config file needed: Go to **Settings** > **Connectors** > **Add custom connector** and enter: ``` https://mcp.scrapebadger.com/mcp ``` Click **Connect**. Your browser opens the ScrapeBadger consent screen — sign in and approve. Access is tied to your account and can be revoked anytime by deactivating your API key in the dashboard. ## Alternative: Config File (API Key) If you prefer API-key auth via a config file: ### Prerequisites * [Claude Desktop](https://claude.ai/download) installed * Node.js 18+ (for `npx mcp-remote`) * ScrapeBadger API key Open Claude Desktop settings, go to **Developer** > **Edit Config**, or edit the file directly: * **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` * **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` Add this to the config file: ```json theme={null} { "mcpServers": { "scrapebadger": { "command": "npx", "args": [ "-y", "mcp-remote", "https://mcp.scrapebadger.com/mcp", "--header", "Authorization: Bearer YOUR_API_KEY" ] } } } ``` Replace `YOUR_API_KEY` with your ScrapeBadger API key. (The older `?api_key=` query parameter still works but is deprecated — URLs leak into logs and shell history; prefer the header.) Fully quit and restart Claude Desktop. The ScrapeBadger tools will appear in the tools menu. Claude Desktop uses stdio transport only. The `npx mcp-remote` package bridges between Claude Desktop's stdio and our hosted HTTP server. ## Verify After restarting, click the tools icon (hammer) in Claude Desktop. You should see 344 ScrapeBadger tools listed (Twitter/X, Google, YouTube, TikTok, Amazon, eBay, Reddit, real estate, and web scraping). ## Examples Try asking Claude: > "Search Twitter for recent posts about AI agents" Claude will call the `twitter_advanced_search` tool automatically. > "Find the top 3 laptops on Google Shopping under \$1500 and resolve the merchant URL for each" Claude will chain `google_shopping_search` with `google_shopping_product_click` for each result. # Cline Source: https://docs.scrapebadger.com/mcp/integrations/cline Connect ScrapeBadger to Cline (VS Code AI agent) via MCP. # Cline ## Setup Click the **MCP Servers** icon in Cline's top navigation > **Configure** tab > "Configure MCP Servers": ```json theme={null} { "mcpServers": { "scrapebadger": { "url": "https://mcp.scrapebadger.com/mcp", "headers": { "Authorization": "Bearer YOUR_API_KEY" } } } } ``` ## Auto-Approve Tools To skip confirmation prompts for specific tools, add `alwaysAllow`: ```json theme={null} { "mcpServers": { "scrapebadger": { "url": "https://mcp.scrapebadger.com/mcp", "headers": { "Authorization": "Bearer YOUR_API_KEY" }, "alwaysAllow": ["twitter_get_trends", "twitter_search_users"] } } } ``` ## Verify After saving, Cline automatically detects the available tools. You should see 344 ScrapeBadger tools in the MCP Servers panel. ## Example tool call Try asking Cline to use a Google tool: > "Search Google Shopping for laptops under \$1500 and resolve the merchant URL for the top result" Cline will call `google_shopping_search` followed by `google_shopping_product_click` automatically. # Codex Source: https://docs.scrapebadger.com/mcp/integrations/codex Connect ScrapeBadger to OpenAI Codex (CLI, IDE extension and Codex app) via MCP with OAuth. # Codex The Codex CLI, IDE extension and Codex app share one MCP configuration, so you only set ScrapeBadger up once. ## Setup ```bash theme={null} codex mcp add scrapebadger --url https://mcp.scrapebadger.com/mcp ``` ```bash theme={null} codex mcp login scrapebadger ``` Your browser opens the ScrapeBadger sign-in and consent screen. Approve it, and Codex stores the token. You don't need an API key. Prefer an API key? Export it and point Codex at the variable instead of running `codex mcp login`: ```bash theme={null} export SCRAPEBADGER_API_KEY=sb_live_... codex mcp add scrapebadger --url https://mcp.scrapebadger.com/mcp --bearer-token-env-var SCRAPEBADGER_API_KEY ``` ## What you can ask Once connected, Codex can call any of ScrapeBadger's tools while it works. Try: > "Pull the latest 20 tweets from @openai and write them to tweets.json" > "Scrape [https://example.com/pricing](https://example.com/pricing) and turn the plans into a TypeScript type" # Continue.dev Source: https://docs.scrapebadger.com/mcp/integrations/continue-dev Connect ScrapeBadger to Continue.dev via MCP. # Continue.dev ## Setup Add to `.continue/config.yaml` in your project: ```yaml theme={null} mcpServers: - name: scrapebadger type: streamable-http url: https://mcp.scrapebadger.com/mcp env: SCRAPEBADGER_API_KEY: YOUR_API_KEY ``` Or drop a JSON config into `.continue/mcpServers/scrapebadger.json`: ```json theme={null} { "mcpServers": { "scrapebadger": { "type": "streamable-http", "url": "https://mcp.scrapebadger.com/mcp", "env": { "SCRAPEBADGER_API_KEY": "YOUR_API_KEY" } } } } ``` Continue.dev can import JSON configs from Claude Desktop, Cursor, or Cline directly into `.continue/mcpServers/`. MCP tools only work in **Agent mode**. ## Tools available ScrapeBadger exposes 344 tools to Continue.dev across Twitter/X, Google, YouTube, TikTok, Amazon, eBay, Reddit, real estate, and web scraping. In Agent mode, ask things like: > "Search Google Shopping for the cheapest 16-inch laptop and resolve the merchant URL" Continue.dev will call `google_shopping_search` followed by `google_shopping_product_click`. # Cursor Source: https://docs.scrapebadger.com/mcp/integrations/cursor Connect ScrapeBadger to Cursor IDE via MCP. # Cursor ## Setup Create or edit `.cursor/mcp.json` (project-level) or `~/.cursor/mcp.json` (global): ```json theme={null} { "mcpServers": { "scrapebadger": { "type": "streamableHttp", "url": "https://mcp.scrapebadger.com/mcp", "headers": { "Authorization": "Bearer YOUR_API_KEY" } } } } ``` ## Verify Open Cursor Settings > MCP. ScrapeBadger should appear as connected with 344 tools. MCP tools only work in **Agent mode** (not Ask or Edit mode). Make sure to select Agent mode when using ScrapeBadger tools. ## Troubleshooting * **Tools not showing?** Restart Cursor after adding the config. * **"streamableHttp" not recognized?** Update Cursor to the latest version. # Gemini CLI Source: https://docs.scrapebadger.com/mcp/integrations/gemini Connect ScrapeBadger to Google Gemini CLI via MCP. # Gemini CLI ## Setup Edit `~/.gemini/settings.json` (or `.gemini/settings.json` in your project): ```json theme={null} { "mcpServers": { "scrapebadger": { "httpUrl": "https://mcp.scrapebadger.com/mcp", "headers": { "Authorization": "Bearer YOUR_API_KEY" } } } } ``` Gemini CLI uses `httpUrl` — not `url`. This is different from Cursor and other tools. ## Verify Run `gemini` and ask it to use a ScrapeBadger tool. The tools will be discovered automatically. The Gemini web app (gemini.google.com) does **not** support custom MCP servers. MCP is available through the Gemini CLI only. ## Examples ScrapeBadger gives Gemini CLI 344 tools across Twitter/X, Google, YouTube, TikTok, Amazon, eBay, Reddit, real estate, and web scraping. Try: ```bash theme={null} gemini "Search Google for 'best react state management 2026' and list the top 5 results" ``` ```bash theme={null} gemini "Find a Razer gaming headset on Google Shopping and resolve the merchant URL" ``` Gemini will discover and call the appropriate `google_search` / `google_shopping_*` tools. # OpenClaw Source: https://docs.scrapebadger.com/mcp/integrations/openclaw Connect ScrapeBadger to OpenClaw personal AI assistant. # OpenClaw [OpenClaw](https://openclaw.ai/) supports three integration methods. Choose the one that fits your needs: ## Option 1: Skill (Recommended) The simplest approach — install from ClawHub: ```bash theme={null} openclaw skills install scrapebadger ``` This teaches the OpenClaw agent how to use the ScrapeBadger API via natural language instructions. ## Option 2: Plugin For richer integration with typed tools: ```bash theme={null} openclaw plugins install @scrapebadger/openclaw-plugin ``` ## Option 3: MCP OpenClaw has a built-in MCP Registry. Connect to our hosted server at `https://mcp.scrapebadger.com/mcp`. ## Authentication Set the `SCRAPEBADGER_API_KEY` environment variable before starting OpenClaw: ```bash theme={null} export SCRAPEBADGER_API_KEY=sb_live_... openclaw ``` ## Tools available ScrapeBadger provides 344 tools to OpenClaw across Twitter/X, Google, YouTube, TikTok, Amazon, eBay, Reddit, real estate, and web scraping. The Google product family alone exposes 29 tools — search, maps, news, shopping (with merchant URL enrichment), trends, jobs, hotels, patents, scholar, and more. # VS Code + Copilot Source: https://docs.scrapebadger.com/mcp/integrations/vscode-copilot Connect ScrapeBadger to VS Code with GitHub Copilot via MCP. # VS Code + GitHub Copilot ## Setup Create `.vscode/mcp.json` in your project root: ```json theme={null} { "inputs": [ { "type": "promptString", "id": "scrapebadger-api-key", "description": "ScrapeBadger API Key", "password": true } ], "servers": { "scrapebadger": { "type": "http", "url": "https://mcp.scrapebadger.com/mcp", "headers": { "Authorization": "Bearer ${input:scrapebadger-api-key}" } } } } ``` VS Code uses `"servers"` — not `"mcpServers"`. This is different from every other tool. ## How It Works The `inputs` array creates a secure prompt for your API key. VS Code will ask for it on first use and store it securely — no hardcoded keys in your config. ## Verify Open the Command Palette (`Cmd+Shift+P`) > "MCP: List Servers". ScrapeBadger should appear. MCP tools only work in Copilot **Agent mode**, not Ask or Edit mode. ScrapeBadger exposes 344 tools (Twitter/X, Google, YouTube, TikTok, Amazon, eBay, Reddit, real estate, web scraping). For Google specifically, try: > "@workspace Use Google Search to find the official Python 3.13 release notes and summarize the new features" Copilot will call `google_search` and process the structured response. # Windsurf Source: https://docs.scrapebadger.com/mcp/integrations/windsurf Connect ScrapeBadger to Windsurf IDE via MCP. # Windsurf ## Setup Edit the MCP config file at: * **macOS/Linux**: `~/.codeium/windsurf/mcp_config.json` * **Windows**: `%USERPROFILE%\.codeium\windsurf\mcp_config.json` Or open via: Windsurf Settings > Cascade > MCP Servers ```json theme={null} { "mcpServers": { "scrapebadger": { "serverUrl": "https://mcp.scrapebadger.com/mcp", "headers": { "Authorization": "Bearer YOUR_API_KEY" } } } } ``` Windsurf uses `serverUrl` — not `url`. This is different from Cursor and other tools. ## Verify Go to Windsurf Settings > Cascade > MCP Servers. ScrapeBadger should appear as connected. Windsurf has a maximum of 100 tools across all MCP servers. ScrapeBadger exposes 344, so Windsurf will only load a subset — disable the tools you don't need in Windsurf's MCP panel, or use a client without a tool cap for full coverage. ## Example Ask Cascade in Agent mode: > "Search Google Shopping for a gaming headset under \$200 and return the merchant URL of the top result" Cascade will call `google_shopping_search` then `google_shopping_product_click`. # MCP Server Source: https://docs.scrapebadger.com/mcp/overview Connect AI agents to ScrapeBadger via Model Context Protocol. 344 tools for Twitter/X, Instagram, Google, YouTube, TikTok, Amazon, eBay, Reddit, real estate, and web scraping. Latest MCP spec (2026-07-28), one-click OAuth for Claude. # MCP Server ScrapeBadger provides a hosted MCP (Model Context Protocol) server at `mcp.scrapebadger.com` that lets AI agents access all ScrapeBadger APIs through structured, typed tools. ## What is MCP? [Model Context Protocol](https://spec.modelcontextprotocol.io/) is an open standard by Anthropic for connecting AI models to external tools and data sources. Instead of writing code, your AI agent discovers and calls ScrapeBadger tools naturally during a conversation. ## Key Features Every ScrapeBadger API endpoint is available as a typed MCP tool with structured parameters, annotations, and output schemas. Hosted at mcp.scrapebadger.com — connect Claude with one click, or add one config snippet to any other AI tool. Works with Claude, Cursor, Windsurf, VS Code, Gemini, ChatGPT, OpenClaw, Cline, and more. No extra cost — MCP uses the same credit-based pricing as the REST API. Twitter/X, Instagram, Facebook, LinkedIn, Google, YouTube, TikTok, Reddit, Amazon, eBay, Walmart, Vinted, Depop, real estate, search engines, LLM answers, and general web scraping — all in one server. Speaks the stateless 2026-07-28 protocol revision and every earlier one; OAuth 2.1 with PKCE, resource indicators, and Client ID Metadata Documents. ## Available Tools | Product | Tools | Description | | - | - | - | | **Twitter/X** | 49 | Profiles, tweets, advanced search, trends, communities, lists, spaces, real-time stream monitors, filter rules | | **Instagram** | 39 | Profiles, posts, reels, stories, highlights, comments, followers, hashtags, locations, audio, search | | **Google** | 33 | Web search (SERP), Images, Videos, Lens, Maps, News, Trends, Jobs, Hotels, Shopping, Patents, Scholar, Finance, Flights | | **YouTube** | 27 | Search, video/Shorts detail, comments, transcripts, channels, playlists, trending, hashtags, community posts, music search | | **TikTok** | 22 | Profiles, videos, comments, transcripts, hashtags, music, search, trending, ad library | | **Facebook** | 15 | Pages, profiles, groups, posts, comments, Marketplace, Ad Library | | **Amazon** | 14 | Product search, PDP detail, offers, reviews, bestsellers, deals, category browse, sellers (20 marketplaces) | | **Reddit** | 12 | Post/subreddit/user search, comment trees, trending, domain posts | | **eBay** | 11 | Active + sold listing search, item detail, reviews, sellers, categories (18 marketplaces) | | **Leboncoin** | 10 | French classifieds search, ad detail, sellers, categories, regions | | **LinkedIn** | 10 | Job search, company jobs, companies, schools, profiles, posts, articles, courses | | **Walmart** | 10 | Product search, category browse, deals, PDP detail, reviews, sellers, stores (US) | | **Vinted** | 10 | Search, item details, sellers, reference data, and 76 mobile reads through `vinted_mobile_operations` / `vinted_mobile_read` | | **Idealista** | 8 | Location suggest, listing search, full-inventory search, property detail + stats, agencies (ES, IT, PT) | | **Immobiliare** | 7 | Listing search, detail, agencies, price insights (IT, ES, GR, LU) | | **DuckDuckGo** | 7 | Web/image/news/video search, autocomplete, instant answers, regions | | **Web Scraping** | 6 | Scrape any URL, anti-bot detection, screenshots, AI extraction, batch jobs | | **Bing** | 6 | Web/image/video/news search, autocomplete (30+ markets) | | **Yahoo** | 6 | Web/image/video/news search, autocomplete, per-country markets | | **Zillow** | 5 | Property search, detail + valuation, agents (US + CA) | | **LoopNet** | 5 | Commercial real estate search, listing detail, brokers | | **Depop** | 5 | Product search, product detail, sellers, markets | | **Redfin** | 5 | Property search, detail, agents, autocomplete | | **Realtor** | 4 | Listing search, property detail, autocomplete (realtor.com + realtor.ca) | | **Baidu** | 4 | Web/news/image search + autocomplete with real target URLs | | **Yandex** | 4 | Web search, image search, reverse image search (CBIR) | | **Apartments.com** | 3 | Rental search and property detail | | **ChatGPT** | 3 | `chatgpt_ask` (answer + citations from the real chatgpt.com), `chatgpt_brand_visibility` (AEO/GEO brand analysis), `chatgpt_list_models` | | **Perplexity** | 3 | Grounded answers with citations + brand-visibility scoring | | **Gemini** | 2 | Answers with cited web sources + brand-visibility scoring | | **Account** | 1 | Credit balance, tier, and rate-limit info | ## Google Tools Google MCP tools are prefixed with `google_` — highlights: | Tool | Description | | - | - | | `google_search` | Web search (SERP) with 21 parameters + knowledge graph, PAA, AI overview | | `google_images_search` | Image search with size/color/type filters | | `google_videos_search` | Video search | | `google_autocomplete` | Search suggestions for a query prefix | | `google_ai_mode_search` | Generative AI answers (udm=50) with references | | `google_lens_search` | Visual image search by URL | | Tool | Description | | - | - | | `google_maps_search` | Search places by text query | | `google_maps_place` | Place detail by place\_id or data\_id | | `google_maps_reviews` | Paginated reviews (sortable) | | `google_maps_photos` | Place photos | | `google_maps_posts` | Business posts | | Tool | Description | | - | - | | `google_shopping_search` | Product search with filters + quick\_filters + ads | | `google_shopping_product` | Product detail with seller list | | `google_shopping_product_click` | Resolve the real merchant URL per product | | Tool | Description | | - | - | | `google_news_search` | News article search | | `google_news_topics` | News by predefined topic | | `google_news_trending` | Trending stories | | `google_trends_interest` | Interest over time (up to 5 terms) | | `google_trends_regions` | Interest by region | | `google_trends_related` | Related topics + queries | | `google_trends_trending` | Real-time trending searches | | `google_jobs_search` | Job listings with filters | | Tool | Description | | - | - | | `google_hotels_search` | Hotel search with dates | | `google_hotels_details` | Property details by property\_token | | `google_patents_search` | Patent document search | | `google_patents_detail` | Full patent by publication number | | `google_scholar_search` | Academic paper search with year filters | | `google_finance_quote` | Stock / index / crypto quotes | | `google_products_detail` | Immersive product detail | ## Quick Start **Using Claude?** No API key needed: In [claude.ai](https://claude.ai) (or Claude Desktop), go to **Settings** > **Connectors** > **Add custom connector** and enter `https://mcp.scrapebadger.com/mcp`. Click **Connect** — you'll be redirected to sign in with your ScrapeBadger account and approve access. That's the whole setup. Ask Claude to search tweets, scrape websites, or look up products — it discovers and calls the right tools automatically. **Using another AI tool?** Sign up at [scrapebadger.com](https://scrapebadger.com), create an API key from the dashboard, and grab the config snippet from the [integration guides](/mcp/integrations/claude-desktop). ## Authentication Two authentication modes are supported: ### OAuth (recommended) Clients that support MCP OAuth can connect without any key handling: add the server URL, sign in with your ScrapeBadger account, and approve the consent screen. This includes claude.ai, Claude Desktop, Claude Code, ChatGPT, [Codex](/mcp/integrations/codex), Cursor, VS Code + Copilot, Gemini CLI, Zed, Microsoft 365 Copilot and Perplexity. The consent screen shows which app is asking and where you'll be sent back to. Access is tied to your account's API key and can be revoked anytime by deactivating that key in the dashboard. ### API key | Method | Example | Best For | | - | - | - | | **Bearer header** | `Authorization: Bearer sb_live_...` | Cursor, Windsurf, VS Code, Cline, mcp-remote (`--header`) | | **Environment variable** | `SCRAPEBADGER_API_KEY=sb_live_...` | Local/stdio installations | | **Query parameter** (deprecated) | `?api_key=sb_live_...` | Legacy configs only — URLs end up in logs and history; switch to the Bearer header or OAuth | ## Protocol & Standards The server tracks the latest MCP specification (revision **2026-07-28**): * **Protocol versions** — speaks the stateless 2026-07-28 revision (per-request versioning, `server/discover`) and serves every earlier revision (2025-11-25, 2025-06-18, …) from the same endpoint, so older clients keep working. Streamable HTTP transport only; the deprecated HTTP+SSE transport is not offered. * **Tool metadata** — all 344 tools carry a human-readable `title`, `readOnlyHint`/`destructiveHint`/`openWorldHint` annotations, and an output schema. Tool results are size-capped to stay within client limits, and the tool list is served with cache hints (`ttlMs`/`cacheScope`) for faster clients. * **OAuth 2.1** — authorization code + PKCE (S256), refresh-token rotation, RFC 8414 authorization-server metadata, RFC 9728 protected-resource metadata, RFC 8707 resource indicators, RFC 9207 `iss` authorization responses, and Client ID Metadata Documents (HTTPS-URL client ids, the 2026-07-28 successor to Dynamic Client Registration — which remains supported for older clients). Loopback redirect URIs match on any port (RFC 8252 §7.3), so native clients that pick a port at sign-in time work, and DCR clients that ask for `client_secret_basic` / `client_secret_post` receive a client secret. ## MCP Endpoint ``` https://mcp.scrapebadger.com/mcp ``` Health check: `https://mcp.scrapebadger.com/health` ## Vinted mobile reads Call `vinted_mobile_operations` to discover parameters and examples, then call `vinted_mobile_read` with `operation`, `market`, and a `parameters` object. See the [mobile API catalog](/vinted/mobile-api) for pricing, sold comparables, seller reviews, shipping, and reference data. # Naver API Overview Source: https://docs.scrapebadger.com/naver/overview Search Naver — South Korea's dominant portal — across web, news, blog, cafe, Knowledge iN, image, video and local, plus the full Naver Shopping stack: rankings, catalog search, SmartStore/Brand storefronts, product detail, reviews & Q&A, and Shopping Live. Clean JSON, no Naver API key required. ## Overview The ScrapeBadger **Naver API** turns `naver.com` — the search portal most of South Korea actually uses — into a clean JSON feed. It covers three areas: * **Search & content** — the web SERP, the dedicated web/news/blog/cafe/ Knowledge iN/image/video/clip verticals, and search-box autocomplete, all with resolved destination URLs and absolute publish timestamps. * **Naver Place** — local business search, full place detail with menus and photos, place reviews, and the place photo viewer. * **Naver Shopping** — the ranking and insight feeds (bestsellers, keyword and brand rankings, curated verticals), product and catalog search with price-comparison, SmartStore and Brand Store storefronts, product detail, reviews & Q\&A, and the full **Shopping Live** broadcast/channel/shortclip stack. All endpoints are `GET`, live under `https://scrapebadger.com/v1/naver/*`, and authenticate with the `X-API-Key` header. Credits are charged per request and reported on the `X-Credits-Used` response header. A request that returns an empty result, or that Naver answers with a challenge, is **not billed**. ## Features * **Web & content verticals** — the integrated [`/search`](/api-reference/endpoint/naver/search) SERP plus the dedicated [`/search/web`](/api-reference/endpoint/naver/search-web), [`/news`](/api-reference/endpoint/naver/news), [`/blog`](/api-reference/endpoint/naver/blog), [`/cafe`](/api-reference/endpoint/naver/cafe), [`/kin`](/api-reference/endpoint/naver/kin) (Knowledge iN), [`/image`](/api-reference/endpoint/naver/image), [`/video`](/api-reference/endpoint/naver/video) and [`/clip`](/api-reference/endpoint/naver/clip) feeds, each with resolved destination URLs and absolute publish times. * **Autocomplete** — Naver's search-box suggestions for 1 credit. * **Naver Place** — local business search, full place detail, reviews and the place [photo viewer](/api-reference/endpoint/naver/place-photos). * **Shopping rankings & insight** — bestseller, keyword and brand rankings, keyword insight, curated deals/verticals/IT-item feeds, and the ranking category trees. * **Shopping search & catalog** — the finder product search and filter facets, filtered search, the deep full-catalog search, and per-catalog price-comparison across sellers. * **SmartStore & Brand Stores** — store profile, category tree, product listing and per-store bestsellers. * **Products, reviews & Q\&A** — full product detail, variant groups, rating summaries, paginated reviews and product Q\&A. * **Shopping Live** — broadcast detail/products/counts/replay, channel profile/ products/broadcasts/shortclips, shortclip detail/products, and the live keyword ranking. ## Market Naver serves **South Korea** only. Results are returned in Korean (`ko-KR`), ranked for Korean users, and requests exit from a Korean IP. There is no market or country parameter — every endpoint is single-market. ## SmartStore vs. Brand Store The storefront, product, review and Q\&A endpoints take a `host` parameter that selects the storefront platform — `smartstore` (Naver SmartStore) or `brand` (Naver Brand Store). Brand Store coverage is the most complete; some SmartStore calls require an extra identifier (`channel_uid` or `checkout_merchant_no`) and may return a partial record. Each endpoint page documents its own requirements. ## Credits Costs are charged per request and reported on the `X-Credits-Used` response header; the live per-endpoint price is also published at `/public/pricing`. The standard tier is **5 credits**, with these exceptions: | Endpoint | Path | Credits | | - | - | - | | Autocomplete | `GET /v1/naver/autocomplete` | 1 | | Shopping categories | `GET /v1/naver/shopping/categories` | 0 (free reference) | | Place detail | `GET /v1/naver/place/{place_id}` | 8 (browser-rendered) | | Everything else | `GET /v1/naver/*` | 5 | The catalog and price-comparison searches ([`/shopping/search-catalog`](/api-reference/endpoint/naver/shopping-search-catalog) and [`/shopping/price-compare`](/api-reference/endpoint/naver/shopping-price-compare)) clear Naver's shopping challenge in a live browser session, so they are the heaviest calls and a page can take up to \~90 seconds. ## Quickstart ```bash cURL theme={null} curl "https://scrapebadger.com/v1/naver/search?query=제주도+맛집" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/naver/search?" + new URLSearchParams({ query: "제주도 맛집" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); console.log(data.result_count, "results returned"); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/naver/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "제주도 맛집"}, ) data = res.json() print(data["result_count"], "results returned") ``` ## Other notes * **Organic `url` values are final destinations** — any Naver redirect wrapper is resolved so you get the real target URL. * **`related_searches[]` and `place_results[]`** appear only when Naver serves them for that query. * **Shopping ids chain together** — take a `category_id` from [`/shopping/categories`](/api-reference/endpoint/naver/shopping-categories), a catalogue `nv_mid` from a search or ranking feed, and a storefront slug from a product URL to move between the shopping endpoints. * **Pagination styles vary by endpoint** — content verticals use `page`, storefront and live lists use `page`/`size`, and the live channel feeds and the place photo viewer use an opaque cursor. Each page documents its own. ## Errors | Status | Meaning | | - | - | | `404` | The place, product or resource does not exist. | | `422` | Naver served a challenge instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | Start from [`/autocomplete`](/api-reference/endpoint/naver/autocomplete) (1 credit) to expand a seed term into real Naver queries, then run [`/search`](/api-reference/endpoint/naver/search) on each suggestion. # Quick Start Source: https://docs.scrapebadger.com/quickstart Get started with the ScrapeBadger API in under 5 minutes. Follow these three steps to make your first API call. ## Step 1: Create an Account Sign up for a free ScrapeBadger account. No credit card required. Create your account and get free credits to start. ## Step 2: Generate an API Key Navigate to your dashboard and create a new API key. You can create multiple keys for different projects. Create and manage your API keys. ## Step 3: Make Your First Request Use your API key to authenticate requests. Include it in the `x-api-key` header. ```bash cURL theme={null} curl -X GET "https://scrapebadger.com/v1/twitter/users/elonmusk/by_username" \ -H "x-api-key: YOUR_API_KEY" ``` ```javascript JavaScript theme={null} const response = await fetch( 'https://scrapebadger.com/v1/twitter/users/elonmusk/by_username', { headers: { 'x-api-key': 'YOUR_API_KEY' } } ); const user = await response.json(); console.log(user.name, user.followers_count); ``` ```python Python theme={null} import requests response = requests.get( 'https://scrapebadger.com/v1/twitter/users/elonmusk/by_username', headers={'x-api-key': 'YOUR_API_KEY'} ) user = response.json() print(f"{user['name']} - {user['followers_count']} followers") ``` ## Example Response ```json theme={null} { "id": "44196397", "username": "elonmusk", "name": "Elon Musk", "description": "Read @TheBoringCompany...", "followers_count": 170000000, "following_count": 500, "tweet_count": 45000, "verified": true, "verified_type": "Business", "profile_image_url": "https://pbs.twimg.com/...", "created_at": "2009-06-02T20:12:29.000Z" } ``` The response includes full user profile data including verification status, follower counts, and account metadata. ## Next Steps Learn about API key management and security best practices. Explore all 50+ endpoints for tweets, users, lists, and more. # Rate Limits Source: https://docs.scrapebadger.com/rate-limits Understand ScrapeBadger API rate limits, tier-based limits, and best practices for handling rate limit errors. ScrapeBadger uses tier-based rate limiting to ensure fair usage and reliable performance for all users. ## How Rate Limiting Works Your rate limit is determined by your account tier. All API keys inherit the same limit from your account. We use a sliding window algorithm for accurate rate limiting. Limits are calculated per minute with smooth request distribution. Every response includes rate limit headers so you can monitor usage and implement smart retry logic. ## Rate Limits by Tier | Tier | Requests/Minute | Description | | - | - | - | | Free | 60 | Default tier for new accounts | | Basic | 300 | For small-scale applications | | Pro | 1,000 | For production applications | | Enterprise | 5,000 | For high-volume applications | ## Rate Limit Headers Every API response includes these headers to help you track your rate limit usage: | Header | Description | Example | | - | - | - | | `X-RateLimit-Limit` | Maximum requests allowed per minute for your tier | `300` | | `X-RateLimit-Remaining` | Requests remaining in the current window | `287` | | `X-RateLimit-Reset` | Unix timestamp when the rate limit window resets | `1703123456` | | `Retry-After` | Seconds until you can retry (only on 429 responses) | `45` | ## Rate Limit Exceeded Response When you exceed your rate limit, the API returns a `429 Too Many Requests` response: ```json theme={null} { "detail": "Rate limit exceeded", "limit": 300, "remaining": 0, "reset_at": 1703123456, "tier": "basic" } ``` ## Handling Rate Limits ```bash cURL theme={null} # Check rate limit headers in response curl -i -H "x-api-key: sb_live_xxx" \ https://scrapebadger.com/v1/twitter/tweets/123 # Response headers: # X-RateLimit-Limit: 300 # X-RateLimit-Remaining: 299 # X-RateLimit-Reset: 1703123456 ``` ```javascript JavaScript theme={null} async function fetchWithRateLimit(url, apiKey) { const response = await fetch(url, { headers: { 'x-api-key': apiKey } }); const remaining = response.headers.get('X-RateLimit-Remaining'); const limit = response.headers.get('X-RateLimit-Limit'); if (response.status === 429) { const retryAfter = response.headers.get('Retry-After'); console.log(`Rate limited. Retry in ${retryAfter} seconds`); await new Promise(r => setTimeout(r, retryAfter * 1000)); return fetchWithRateLimit(url, apiKey); } console.log(`Requests remaining: ${remaining}/${limit}`); return response.json(); } ``` ```python Python theme={null} import time import requests def fetch_with_rate_limit(url: str, api_key: str): response = requests.get(url, headers={"x-api-key": api_key}) remaining = response.headers.get("X-RateLimit-Remaining") limit = response.headers.get("X-RateLimit-Limit") if response.status_code == 429: retry_after = int(response.headers.get("Retry-After", 60)) print(f"Rate limited. Retry in {retry_after} seconds") time.sleep(retry_after) return fetch_with_rate_limit(url, api_key) print(f"Requests remaining: {remaining}/{limit}") return response.json() ``` ## Best Practices Check `X-RateLimit-Remaining` on each response to proactively slow down before hitting limits. When rate limited, wait the `Retry-After` time and consider increasing wait time on repeated limits. Queue requests and process them at a controlled rate to stay within your limits. Cache API responses where appropriate to reduce the number of requests you need to make. **Avoid Rate Limit Abuse** Repeatedly hitting rate limits or attempting to bypass them may result in temporary or permanent restrictions on your account. * Don't create multiple accounts to circumvent limits * Don't use rotating API keys to bypass rate limiting * Contact support if you need higher limits ## FAQ Rate limits are applied per API key using a sliding window algorithm. Each API key has its own separate rate limit counter based on your account tier. The API returns a 429 Too Many Requests response with details about when you can retry. Use the `Retry-After` header to know when to try again. Yes, all requests (successful or not) count against your rate limit. However, rate limits are generous and designed to accommodate normal usage patterns. All API keys inherit the rate limit from your account tier. To get higher rate limits, upgrade your account tier. Every API response includes rate limit headers (`X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`) so you can track your usage in real-time. *** Need higher rate limits? Contact us at [sales@scrapebadger.com](mailto:sales@scrapebadger.com). # Realtor.com Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/realtor/overview Scrape US (realtor.com) and Canada (realtor.ca) real-estate listings — search, full property detail, price/tax history, schools, agents, and open houses — with structured JSON responses. ## Scraper API for Realtor.com & Realtor.ca Search for-sale, for-rent, sold, and pending listings, pull **full property detail** with price and tax history, schools, and agent contacts, and autocomplete locations across **realtor.com (US)** and **realtor.ca (Canada)** — a unified real-estate API over both markets. The API handles authentication, anti-bot bypass, and market routing automatically. ## Key Features One API over **realtor.com (US, USD)** and **realtor.ca (Canada, CAD)**. Pick a market with the `market` parameter. Beds, baths, sqft, lot size, year built, HOA, price-per-sqft, coordinates, photos, videos, and virtual tours. Full **price history**, **tax history**, and value estimates on the [`/v1/realtor/properties/{id}`](/api-reference/endpoint/realtor/get-property) detail endpoint. Nearby schools with ratings, plus agent/office/broker contact details (name, email, phones). Automatic session management, Chrome TLS impersonation, and fingerprint rotation to avoid blocks. Requests are routed through proxies matching the target market for accurate listings and availability. realtor.ca (Canada) caps bounding-box searches at roughly **600 results per box**. For dense metros, split large areas into smaller `lat_min`/`lat_max`/`lng_min`/`lng_max` tiles. ## Supported Markets The API covers two national real-estate portals. Use the `market` query parameter to target one. | Market | Portal | Country | Currency | Locale | | - | - | - | - | - | | :us: `us` | realtor.com | US | USD | en-US | | :canada: `ca` | realtor.ca | CA | CAD | en-CA | If no `market` is specified, it defaults to `us`. Use the [`/v1/realtor/markets`](/api-reference/endpoint/realtor/list-markets) endpoint to get the full list (with domain, currency, and locale) programmatically. ## Quick Start ```javascript Node.js theme={null} import ScrapeBadger from "scrapebadger"; const client = new ScrapeBadger({ apiKey: "YOUR_API_KEY" }); const results = await client.realtor.search({ location: "Austin, TX", market: "us", status: "for_sale", }); console.log(results.results); ``` ```python Python theme={null} from scrapebadger import ScrapeBadger client = ScrapeBadger(api_key="YOUR_API_KEY") results = client.realtor.search( location="Austin, TX", market="us", status="for_sale", ) print(results.results) ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/realtor/search?location=Austin,+TX&market=us&status=for_sale" \ -H "x-api-key: YOUR_API_KEY" ``` ## Endpoints | Endpoint | Method | Description | | - | - | - | | [`/v1/realtor/search`](/api-reference/endpoint/realtor/search) | GET | Search a market for listings | | [`/v1/realtor/properties/{property_id}`](/api-reference/endpoint/realtor/get-property) | GET | Full detail for a single property | | [`/v1/realtor/autocomplete`](/api-reference/endpoint/realtor/autocomplete) | GET | Location autocomplete suggestions | | [`/v1/realtor/markets`](/api-reference/endpoint/realtor/list-markets) | GET | List all supported markets | ## Credit Costs | Endpoint | Cost | | - | - | | Search | 8 credits | | Get property detail | 10 credits | | Autocomplete | 2 credits | | List markets | 0 credits | | Failed requests | 0 credits | ## Authentication All requests require your API key in the `X-API-Key` header: ```bash theme={null} curl "https://scrapebadger.com/v1/realtor/search?location=Miami,+FL" \ -H "X-API-Key: YOUR_API_KEY" ``` ## Anti-Bot Handling Both realtor.com and realtor.ca protect their listings with IP-reputation scoring, TLS/HTTP-2 fingerprinting, and server-side rendering. ScrapeBadger clears these automatically using Chrome TLS impersonation on sessions matched to the target market. You never need to manage proxies, sessions, or CAPTCHAs. For accurate listings and availability, requests are routed through proxies in the market's country. This is handled automatically based on the `market` parameter. ## Rich Datapoints Every property carries a deep set of structured fields: | Group | Fields | | - | - | | **Pricing** | `list_price`, `list_price_formatted`, `price_per_sqft`, `price_reduced_amount`, `hoa_fee`, `last_sold_price` | | **Size** | `beds`, `baths`, `baths_full`, `baths_half`, `sqft`, `lot_sqft`, `year_built`, `stories`, `garage`, `rooms`, `parking_spaces` | | **Location** | `address` (line, city, state, postal, county, neighborhood), `coordinate` (lat/lon) | | **Media** | `primary_photo`, `photos[]`, `photo_count`, `videos[]`, `virtual_tours[]` | | **History** | `price_history[]`, `tax_history[]`, `estimates[]`, `days_on_market`, `last_sold_date_at` | | **Context** | `schools[]`, `amenities[]`, `details[]`, `open_houses[]`, `agents[]`, `flags` (new/pending/foreclosure/…) | Search returns each result as a `Property`; the [property detail](/api-reference/endpoint/realtor/get-property) endpoint returns a `PropertyDetail` that adds `details`, `amenities`, `tax_history`, `price_history`, `schools`, and `estimates`. ## Next Steps Full API reference for searching the realtor.com / realtor.ca catalogs Retrieve full detail, price/tax history, schools, and agents for a property *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Realtor.com, Move, Inc., the National Association of REALTORS®, or the Canadian Real Estate Association. "REALTOR®" is a registered collective membership mark owned by the National Association of REALTORS® (NAR); realtor.com is operated by Move, Inc. (a News Corp company) and realtor.ca by the Canadian Real Estate Association. Used here only to describe the platforms this scraper is designed to work with.* # Reddit Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/reddit/overview Extract posts, comments, subreddits, and user data from Reddit with structured JSON responses. 21 endpoints covering search, listings, comment trees, and wiki content. ## Scraper API for Reddit Search posts, fetch comment trees, explore subreddits, and retrieve user profiles from Reddit. The API handles TLS fingerprinting, proxy rotation, and anti-bot bypass automatically — no Reddit API key or OAuth setup needed. ## Key Features Search, posts, comments, subreddits, users, wiki, trending, and cross-post detection. We handle all authentication and rate limiting. Just use your ScrapeBadger API key. Full nested comment threads with configurable depth control (0-10 levels). Full Reddit search operators: title:, author:, subreddit:, flair:, AND/OR/NOT. Automatic TLS fingerprint rotation and residential proxy routing. First-class support via the ScrapeBadger Node.js and Python SDKs. ## Quick Start ```javascript Node.js theme={null} import ScrapeBadger from 'scrapebadger'; const client = new ScrapeBadger({ apiKey: 'YOUR_API_KEY' }); // Search posts const results = await client.reddit.search.posts({ q: 'artificial intelligence', sort: 'top', t: 'week', limit: 10, }); console.log(results.posts); ``` ```python Python theme={null} from scrapebadger import ScrapeBadger client = ScrapeBadger(api_key="YOUR_API_KEY") # Search posts results = client.reddit.search.posts( q="artificial intelligence", sort="top", t="week", limit=10, ) print(results.posts) ``` ```bash cURL theme={null} curl -X GET "https://scrapebadger.com/v1/reddit/search/posts?q=artificial+intelligence&sort=top&t=week&limit=10" \ -H "Authorization: Bearer YOUR_API_KEY" ``` ## Endpoints ### Search | Endpoint | Credits | Description | | - | - | - | | `GET /v1/reddit/search/posts` | 2 | Search posts globally or within a subreddit | | `GET /v1/reddit/search/subreddits` | 2 | Search for subreddits by keyword | | `GET /v1/reddit/search/users` | 2 | Search for Reddit users | | `GET /v1/reddit/domains/{domain}/posts` | 2 | Get posts linking to a specific domain | ### Posts | Endpoint | Credits | Description | | - | - | - | | `GET /v1/reddit/posts/trending` | 1 | Trending posts from Reddit's front page | | `GET /v1/reddit/posts/{post_id}` | 2 | Get post details by ID | | `GET /v1/reddit/posts/{post_id}/comments` | 3 | Comment tree with depth control | | `GET /v1/reddit/posts/{post_id}/duplicates` | 3 | Cross-posts and duplicates | ### Subreddits | Endpoint | Credits | Description | | - | - | - | | `GET /v1/reddit/subreddits/{subreddit}` | 2 | Subreddit metadata | | `GET /v1/reddit/subreddits/{subreddit}/posts` | 2 | Subreddit posts (hot/new/top/rising) | | `GET /v1/reddit/subreddits/{subreddit}/rules` | 1 | Subreddit rules | | `GET /v1/reddit/subreddits/{subreddit}/wiki` | 1 | List wiki pages | | `GET /v1/reddit/subreddits/{subreddit}/wiki/{page}` | 3 | Wiki page content | | `GET /v1/reddit/subreddits/popular` | 1 | Popular subreddits | | `GET /v1/reddit/subreddits/new` | 1 | New subreddits | ### Users | Endpoint | Credits | Description | | - | - | - | | `GET /v1/reddit/users/{username}` | 2 | User profile and karma | | `GET /v1/reddit/users/{username}/posts` | 2 | User's submitted posts | | `GET /v1/reddit/users/{username}/comments` | 2 | User's comment history | | `GET /v1/reddit/users/{username}/moderated` | 3 | Subreddits user moderates | | `GET /v1/reddit/users/{username}/trophies` | 1 | User's trophy case | ## Pagination All listing endpoints use cursor-based pagination with `after` and `before` parameters. ```json theme={null} { "posts": [...], "pagination": { "after": "t3_abc123", "before": null, "count": 25, "limit": 25 } } ``` Pass the `after` value as a query parameter to get the next page of results. The maximum `limit` per request is 100. ## Search Syntax The search endpoints support Reddit's full query syntax: | Operator | Example | Description | | - | - | - | | `title:` | `title:python` | Search in post titles | | `author:` | `author:spez` | Filter by author | | `subreddit:` | `subreddit:programming` | Filter by subreddit | | `flair:` | `flair:Discussion` | Filter by flair | | `site:` | `site:github.com` | Filter by link domain | | `nsfw:yes` | `nsfw:yes` | Include NSFW posts | | `self:yes` | `self:yes` | Only text posts | | `AND` / `OR` / `NOT` | `python AND tutorial` | Boolean operators | ## Response Fields These tables list every field the API returns. Fields Reddit only populates for the account that owns the content (`saved`, `clicked`, `likes`, ...) and moderator-only fields are deliberately omitted — they are meaningless for a scraping API. ### Post Object | Field | Type | Description | | - | - | - | | `id` | string | Reddit post ID (e.g. `1obwkbb`) | | `fullname` | string | Reddit fullname with `t3_` prefix | | `title` | string | Post title | | `author` | string | Author username (`[deleted]` if removed) | | `author_fullname` | string \| null | Author fullname (`t2_...`) | | `selftext` | string | Plain-text body (empty for link posts) | | `selftext_html` | string \| null | HTML-rendered body | | `url` | string | Link target, or the gallery/self-post URL | | `permalink` | string | Reddit permalink path (e.g. `/r/python/comments/...`) | | `domain` | string | Link domain (e.g. `github.com`, `self.python`) | | `subreddit` | string | Subreddit name (no prefix) | | `subreddit_id` | string \| null | Subreddit fullname (`t5_...`) | | `subreddit_name_prefixed` | string \| null | Subreddit with prefix (e.g. `r/python`) | | `subreddit_type` | string \| null | `public`, `private`, `restricted`, `archived` | | `subreddit_subscribers` | number | Subscriber count at time of fetch | | `score` | number | Net score (ups − downs) | | `ups` | number | Upvote count | | `downs` | number | Downvote count (Reddit reports 0) | | `upvote_ratio` | number | Ratio of upvotes (0.0–1.0) | | `num_comments` | number | Total comment count | | `num_crossposts` | number | Number of cross-posts | | `total_awards_received` | number | Total awards received | | `view_count` | number \| null | View count (null unless the account owns the post) | | `gilded` | number | Number of times gilded | | `created_utc` | number | Creation Unix timestamp | | `created_at` | string \| null | ISO 8601 UTC timestamp (e.g. `2025-10-20T22:56:45+00:00`) | | `edited` | number \| boolean | `false`, or the edit Unix timestamp | | `is_self` | boolean | True for text posts | | `is_video` | boolean | True for native Reddit video | | `is_gallery` | boolean | True for multi-image galleries — see [Post images](#post-images) | | `is_meta` | boolean | True for Reddit meta posts | | `is_original_content` | boolean | OC tag | | `is_robot_indexable` | boolean | Whether search engines can index the post | | `is_crosspostable` | boolean | Allowed to be cross-posted | | `is_reddit_media_domain` | boolean | Media is hosted on Reddit's own CDN | | `media_only` | boolean | Post body is media with no text | | `is_nsfw` | boolean | NSFW flag (Reddit's `over_18`) | | `is_spoiler` | boolean | Spoiler flag | | `is_stickied` | boolean | Pinned to top of subreddit | | `locked` | boolean | Locked from new comments | | `archived` | boolean | Older than 6 months (no new comments) | | `pinned` | boolean | Pinned to the author's profile | | `quarantine` | boolean | Subreddit is quarantined | | `hide_score` | boolean | Score hidden by subreddit settings | | `contest_mode` | boolean | Comments randomised, scores hidden | | `allow_live_comments` | boolean | Live comment updates enabled | | `send_replies` | boolean | Author receives inbox replies | | `distinguished` | string \| null | `moderator`, `admin`, or null | | `removed_by_category` | string \| null | Removal reason category (e.g. `moderator`, `deleted`) | | `suggested_sort` | string \| null | Subreddit's suggested comment sort | | `discussion_type` | string \| null | `CHAT` for live chat posts, else null | | `top_awarded_type` | string \| null | Highest award tier received | | `link_flair_text` | string \| null | Post flair text | | `link_flair_type` | string \| null | `text` or `richtext` | | `link_flair_css_class` | string \| null | Flair CSS class | | `link_flair_template_id` | string \| null | Reddit's flair template UUID | | `link_flair_background_color` | string \| null | Flair background hex | | `link_flair_text_color` | string \| null | `light` or `dark` | | `author_flair_text` | string \| null | Author's flair on this subreddit | | `author_flair_type` | string \| null | `text` or `richtext` | | `author_flair_css_class` | string \| null | Author flair CSS class | | `author_flair_template_id` | string \| null | Author flair template UUID | | `author_flair_background_color` | string \| null | Author flair background hex | | `author_flair_text_color` | string \| null | `light` or `dark` | | `author_premium` | boolean | Author has Reddit Premium | | `author_patreon_flair` | boolean | Author shows Patreon flair | | `thumbnail` | string \| null | Thumbnail URL (\~140px), or `self`/`default`/`nsfw` | | `thumbnail_width` | number \| null | Thumbnail width in pixels | | `thumbnail_height` | number \| null | Thumbnail height in pixels | | `preview_image` | string \| null | Full-resolution preview image URL — see [Post images](#post-images) | | `preview_image_width` | number \| null | Preview image width in pixels | | `preview_image_height` | number \| null | Preview image height in pixels | | `media` | object \| null | Embedded media (Reddit video, oEmbed payload) | | `media_embed` | object \| null | Embed HTML and dimensions | | `secure_media` | object \| null | HTTPS variant of `media` | | `secure_media_embed` | object \| null | HTTPS variant of `media_embed` | | `gallery_images` | array | Gallery images in poster order — see [Post images](#post-images) | | `all_awardings` | array | Award objects (`id`, `name`, `count`, `icon_url`, …) | | `gildings` | object | Gilding counts by tier | ### Comment Object | Field | Type | Description | | - | - | - | | `id` | string | Comment ID | | `fullname` | string | Comment fullname with `t1_` prefix | | `body` | string | Comment text (plain) | | `body_html` | string \| null | Comment text (HTML-rendered) | | `author` | string | Author username | | `author_fullname` | string \| null | Author fullname (`t2_...`) | | `subreddit` | string | Subreddit name | | `subreddit_id` | string \| null | Subreddit fullname (`t5_...`) | | `subreddit_name_prefixed` | string \| null | Subreddit with prefix | | `subreddit_type` | string \| null | `public`, `private`, `restricted` | | `post_id` | string \| null | Parent post fullname (Reddit's `link_id`) | | `parent_id` | string \| null | Parent thing fullname (post or comment) | | `permalink` | string | Reddit permalink path | | `score` | number | Net score | | `ups` | number | Upvote count | | `downs` | number | Downvote count (Reddit reports 0) | | `controversiality` | number | 1 if contested, else 0 | | `total_awards_received` | number | Total awards received | | `gilded` | number | Number of times gilded | | `score_hidden` | boolean | Score hidden (new or contest-mode comment) | | `depth` | number | Nesting level (0 = top-level) | | `created_utc` | number | Creation Unix timestamp | | `created_at` | string \| null | ISO 8601 UTC timestamp | | `edited` | number \| boolean | `false`, or the edit Unix timestamp | | `is_submitter` | boolean | True if the author is the post's author (OP) | | `is_stickied` | boolean | Pinned to top of the thread | | `locked` | boolean | Locked from replies | | `archived` | boolean | Older than 6 months | | `collapsed` | boolean | Collapsed by default | | `collapsed_reason` | string \| null | Why it was collapsed | | `send_replies` | boolean | Author receives inbox replies | | `distinguished` | string \| null | `moderator`, `admin`, or null | | `comment_type` | string \| null | Comment type, if any | | `author_flair_text` | string \| null | Author's flair on this subreddit | | `author_flair_type` | string \| null | `text` or `richtext` | | `author_flair_css_class` | string \| null | Author flair CSS class | | `author_flair_template_id` | string \| null | Author flair template UUID | | `author_flair_background_color` | string \| null | Author flair background hex | | `author_flair_text_color` | string \| null | `light` or `dark` | | `author_premium` | boolean | Author has Reddit Premium | | `all_awardings` | array | Award objects | | `gildings` | object | Gilding counts by tier | | `replies` | array | Nested comments (recursive, to the requested depth) | ### Subreddit Object | Field | Type | Description | | - | - | - | | `id` | string | Subreddit ID | | `fullname` | string | Subreddit fullname with `t5_` prefix | | `name` | string | Subreddit name (no prefix) | | `display_name_prefixed` | string \| null | E.g. `r/python` | | `title` | string | Short display title | | `description` | string | Sidebar description (markdown) | | `description_html` | string \| null | Sidebar description (HTML) | | `public_description` | string | Short public description (markdown) | | `public_description_html` | string \| null | Short public description (HTML) | | `url` | string | Subreddit path (e.g. `/r/python/`) | | `subscribers` | number | Member count | | `created_utc` | number | Creation Unix timestamp | | `created_at` | string \| null | ISO 8601 UTC timestamp | | `subreddit_type` | string \| null | `public`, `private`, `restricted`, `archived` | | `lang` | string \| null | Primary language code | | `is_nsfw` | boolean | NSFW subreddit (Reddit's `over18`) | | `quarantine` | boolean | Subreddit is quarantined | | `wiki_enabled` | boolean | Wiki is enabled | | `over18` | boolean | Raw Reddit NSFW flag (mirrors `is_nsfw`) | | `submission_type` | string \| null | `any`, `link`, `self` | | `submit_text` | string \| null | Submit-page guidance (markdown) | | `submit_text_html` | string \| null | Submit-page guidance (HTML) | | `submit_text_label` | string \| null | Text-post button label | | `submit_link_label` | string \| null | Link-post button label | | `allow_images` | boolean | Image posts allowed | | `allow_videos` | boolean | Video posts allowed | | `allow_galleries` | boolean | Gallery posts allowed | | `allow_polls` | boolean | Poll posts allowed | | `spoilers_enabled` | boolean | Spoiler tagging enabled | | `original_content_tag_enabled` | boolean | OC tagging enabled | | `all_original_content` | boolean | All posts must be OC | | `restrict_posting` | boolean | Posting is restricted | | `restrict_commenting` | boolean | Commenting is restricted | | `free_form_reports` | boolean | Free-form reports allowed | | `show_media` | boolean | Thumbnails shown by default | | `accept_followers` | boolean | Followers accepted | | `link_flair_enabled` | boolean | Post flair enabled | | `link_flair_position` | string \| null | `left`, `right`, or empty | | `comment_score_hide_mins` | number | Minutes before comment scores show | | `suggested_comment_sort` | string \| null | Default comment sort | | `advertiser_category` | string \| null | Ad category | | `community_icon` | string \| null | Redesign community icon URL | | `icon_img` | string \| null | Subreddit icon URL | | `banner_img` | string \| null | Banner image URL | | `banner_background_image` | string \| null | Redesign banner image URL | | `header_img` | string \| null | Legacy header image URL | | `header_title` | string \| null | Header hover title | | `primary_color` | string \| null | Theme primary colour hex | | `key_color` | string \| null | Theme key colour hex | | `banner_background_color` | string \| null | Banner background hex | ### User Object | Field | Type | Description | | - | - | - | | `id` | string | User ID (no `t2_` prefix) | | `name` | string | Username | | `display_name_prefixed` | string \| null | E.g. `u/spez` | | `link_karma` | number | Post karma | | `comment_karma` | number | Comment karma | | `awardee_karma` | number | Karma from awards received | | `awarder_karma` | number | Karma from awards given | | `total_karma` | number | Sum of all karma types | | `created_utc` | number | Account creation Unix timestamp | | `created_at` | string \| null | ISO 8601 UTC timestamp | | `is_gold` | boolean | Has Reddit Premium | | `is_employee` | boolean | Reddit employee | | `is_mod` | boolean | Moderates at least one subreddit | | `is_friend` | boolean | Friend of the requesting account (always false) | | `verified` | boolean | Account is verified | | `has_verified_email` | boolean | Email is verified | | `hide_from_robots` | boolean | Opted out of search engine indexing | | `accept_followers` | boolean | Accepts followers | | `icon_img` | string \| null | Avatar URL | | `snoovatar_img` | string \| null | Snoovatar URL (empty if unset) | | `subreddit` | object \| null | The user's profile subreddit (`u/`) | ## Post images Reddit stores a post's images in two different places depending on the post type, so ScrapeBadger surfaces both. ### Galleries When `is_gallery` is `true`, every image is listed in `gallery_images` **in the order the poster arranged them**, at full source resolution. Deleted or still-processing slots are omitted. | Field | Type | Description | | - | - | - | | `media_id` | string | Reddit's identifier for the image within the gallery | | `url` | string | Full-resolution source URL (the `.gif` for animated items) | | `width` | number \| null | Source width in pixels | | `height` | number \| null | Source height in pixels | | `mime_type` | string \| null | E.g. `image/jpg`, `image/png`, `image/gif` | | `mp4_url` | string \| null | Animated items only: Reddit's mp4 transcode; null for stills | ```json theme={null} { "post": { "id": "1vbjcq5", "is_gallery": true, "url": "https://www.reddit.com/gallery/1vbjcq5", "gallery_images": [ { "media_id": "uaq38k4ojigh1", "url": "https://preview.redd.it/uaq38k4ojigh1.jpg?width=4712&format=pjpg&auto=webp&s=...", "width": 4712, "height": 2668, "mime_type": "image/jpg", "mp4_url": null } ] } } ``` A gallery post's `url` points at `reddit.com/gallery/` and its `thumbnail` is only \~140px wide. Use `gallery_images` for the actual images. ### Single image, video and link posts `thumbnail` is at most \~140px wide. For the full-size image: | Post type | Full-resolution image | | - | - | | Single image | `url` — the direct file on `i.redd.it` (also in `preview_image`) | | Link post | `preview_image` — the link card's image, the only full-size copy | | Native video | `preview_image` is the poster frame; the video is under `media` / `secure_media` | | Self / text post | Usually none — `preview_image` is `null` | ```json theme={null} { "domain": "abc.net.au", "thumbnail": "https://external-preview.redd.it/zGHG...jpeg?width=140&height=78&crop=140:78,smart&auto=webp&s=...", "preview_image": "https://external-preview.redd.it/zGHG...jpeg?auto=webp&s=...", "preview_image_width": 862, "preview_image_height": 485 } ``` `preview.redd.it` and `external-preview.redd.it` URLs are signed. Use them exactly as returned — changing `width`/`height`, or stripping or re-ordering the query string, invalidates the signature and Reddit answers `403`. ## Rate Limits Reddit Scraper API requests are subject to the same rate limits as all ScrapeBadger endpoints. See [Rate Limits](/rate-limits) for details. *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Reddit. "Reddit" is a trademark of Reddit, Inc., used here only to describe the platform this scraper is designed to work with.* # SDKs Source: https://docs.scrapebadger.com/sdks Official ScrapeBadger SDKs for 12 languages, all generated from the same OpenAPI spec. Every SDK below exposes the same API surface — 29 scrapers, 400+ operations — because they are all generated from the ScrapeBadger OpenAPI specification. A new endpoint lands in every language at the same time. Authentication is identical everywhere: pass your API key and the SDK sends it as the `x-api-key` header. ## Installation | Language | Install | Repository | | - | - | - | | Node.js / TypeScript | `npm install scrapebadger` | [scrapebadger-node](https://github.com/scrape-badger/scrapebadger-node) | | Python | `pip install scrapebadger` | [scrapebadger-python](https://github.com/scrape-badger/scrapebadger-python) | | Go | `go get github.com/scrape-badger/scrapebadger-go` | [scrapebadger-go](https://github.com/scrape-badger/scrapebadger-go) | | Rust | `cargo add scrapebadger-sdk` | [scrapebadger-rust](https://github.com/scrape-badger/scrapebadger-rust) | | PHP | `composer require scrape-badger/scrapebadger-php` | [scrapebadger-php](https://github.com/scrape-badger/scrapebadger-php) | | C# / .NET | `dotnet add package ScrapeBadger` | [scrapebadger-csharp](https://github.com/scrape-badger/scrapebadger-csharp) | | Java | `com.scrapebadger:scrapebadger:0.1.0` (Maven Central) | [scrapebadger-java](https://github.com/scrape-badger/scrapebadger-java) | | Kotlin | `com.scrapebadger:scrapebadger-kotlin:0.1.0` (Maven Central) | [scrapebadger-kotlin](https://github.com/scrape-badger/scrapebadger-kotlin) | | Ruby | `gem install scrapebadger` | [scrapebadger-ruby](https://github.com/scrape-badger/scrapebadger-ruby) | | Swift | SPM: `https://github.com/scrape-badger/scrapebadger-swift` from `0.1.0` | [scrapebadger-swift](https://github.com/scrape-badger/scrapebadger-swift) | | Dart / Flutter | `dart pub add scrapebadger` | [scrapebadger-dart](https://github.com/scrape-badger/scrapebadger-dart) | | C++ | source releases (cpprestsdk, CMake) | [scrapebadger-cpp](https://github.com/scrape-badger/scrapebadger-cpp) | Each repository's README documents every operation with per-language examples. ## Example ```python Python theme={null} import requests response = requests.get( 'https://scrapebadger.com/v1/twitter/users/elonmusk/by_username', headers={'x-api-key': 'YOUR_API_KEY'} ) print(response.json()) ``` ```go Go theme={null} package main import ( "context" "fmt" scrapebadger "github.com/scrape-badger/scrapebadger-go" ) func main() { cfg := scrapebadger.NewConfiguration() cfg.AddDefaultHeader("x-api-key", "YOUR_API_KEY") client := scrapebadger.NewAPIClient(cfg) user, _, err := client.TwitterAPI. TwitterGetUserByUsername(context.Background(), "elonmusk").Execute() if err != nil { panic(err) } fmt.Println(user) } ``` The generated SDK repositories are replaced wholesale on every API change — never send pull requests to them. Issues and feature requests belong on the [roadmap](https://github.com/scrape-badger/roadmap). # Teams Source: https://docs.scrapebadger.com/teams Share one ScrapeBadger account with colleagues — invite members, grant them permissions, and manage member and service API keys. Teams let a company use one ScrapeBadger balance from several user accounts. Each member signs in with their own account, and the team's API keys draw credits from the **team owner's** balance and use the owner's rate limit. Create a team on the [Teams](https://scrapebadger.com/dashboard/teams) page. ## Roles | Role | What they can do | | - | - | | **Owner** | Everything. Pays for the team's usage. The only one who can invite or manage admins, and delete the team. Can't leave the team. | | **Admin** | Invite and remove members, change their permissions, and manage every team key. | | **Member** | See the team's keys, plus whatever an admin grants them (below). | ## Member permissions Admins grant plain members any of these: | Permission | Allows | | - | - | | **Create API keys** | Create their own member keys. | | **Delete any key** | Disable or delete any member's key. | | **Manage service keys** | Create, edit, view and delete the team's service keys. | A member can always edit, view, disable and delete the keys they created themselves. ## Member keys and service keys Belong to the member who created them. They stop working the moment that member leaves or is removed from the team. Nobody else — not even the owner — can view a member's key. Owned by the team, not a person, so they keep working when people come and go. Use them for production systems. Only members with **Manage service keys** can view or change them. Both kinds support notes, expiry dates, [API permissions](/authentication#api-key-permissions) and [IP restrictions](/authentication#ip-restrictions), exactly like personal keys. A team key calling an API it isn't permitted to call gets `403 insufficient_scope`. ## Inviting people Admins invite by email from the team's **Members** tab, choosing the role and, for members, their permissions. The invitee gets an email with a link that: * works only for the invited email address, on an account whose email is verified * expires after 7 days * can be revoked from the pending invitations list Invitees can also accept from the [Teams](https://scrapebadger.com/dashboard/teams) page once they're signed in. Inviting the same email again replaces the earlier invitation. ## Audit log Owners and admins see an **Audit log** tab on the team page: a permanent, read-only record of who did what and when. | Category | Events recorded | | - | - | | Team | team created, renamed | | Invitations | sent (with role and permissions), revoked, accepted, declined | | Members | role or permission changes (before → after), removed, left | | API keys | created, edited (each changed field, before → after, including API permissions), enabled, disabled, deleted — also when a member's keys are deleted because they left — and **every time a key's secret was viewed** | Each entry shows the person who acted, the time, and the IP address it came from. Filter by category, and expand an entry to see the exact changes. Entries cannot be edited or deleted; they are removed only if the team itself is deleted. ## Leaving and deleting * A member or admin can leave from the team's **Settings** tab. Their member keys are deleted; service keys are unaffected. * The owner can delete the team, which immediately and permanently deletes every team key. # TikTok Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/tiktok/overview Scrape TikTok user profiles, videos, comments, transcripts, hashtags, music, search, trending, TikTok Shop e-commerce (best sellers, categories, product search and detail), and the EU ad library with structured JSON responses. ## Scraper API for TikTok Fetch full user profiles, posted videos, comments and replies, video transcripts, hashtag and music detail, run keyword search across videos/users/hashtags, pull trending videos/hashtags/songs, read TikTok Shop's best sellers, categories, product search and product detail, and query TikTok's EU Commercial Content (ad transparency) library. The API handles request signing, anti-bot bypass, and regional proxy routing automatically. ## Key Features Full user profiles with stats and verification, plus posted videos and reposts with cursor pagination. Top-level comments, threaded replies, and ASR voice-to-text transcripts with subtitle tracks. Keyword search across videos, users, and hashtags, plus a general Top-feed search. US mobile discovery videos, hashtags and songs. Historical windows and rank-change deltas are unavailable. Search TikTok's EU Commercial Content Library by keyword or advertiser id. First-class support via the ScrapeBadger Node.js and Python SDKs. ## Supported Regions TikTok content is region-aware. Use the `region` query parameter (ISO 3166-1 alpha-2) on any endpoint to route the request through a proxy and signer for that locale. It defaults to `US`. Use the [`/v1/tiktok/regions`](/api-reference/endpoint/tiktok/list-regions) endpoint to get the full list of supported regions (with locale and country code) programmatically. ## Quick Start ```javascript Node.js theme={null} import ScrapeBadger from "scrapebadger"; const client = new ScrapeBadger({ apiKey: "YOUR_API_KEY" }); const profile = await client.tiktok.getUser({ username: "charlidamelio", region: "US", }); console.log(profile.user.stats.follower_count); ``` ```python Python theme={null} from scrapebadger import ScrapeBadger client = ScrapeBadger(api_key="YOUR_API_KEY") profile = client.tiktok.get_user( username="charlidamelio", region="US", ) print(profile.user.stats.follower_count) ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/tiktok/users/charlidamelio?region=US" \ -H "x-api-key: YOUR_API_KEY" ``` ## Endpoints | Endpoint | Method | Description | | - | - | - | | [`/v1/tiktok/users/{username}`](/api-reference/endpoint/tiktok/get-user-profile) | GET | Full user profile by @handle | | [`/v1/tiktok/users/{username}/videos`](/api-reference/endpoint/tiktok/get-user-videos) | GET | A user's posted videos | | [`/v1/tiktok/users/{username}/reposts`](/api-reference/endpoint/tiktok/get-user-reposts) | GET | Videos a user has reposted | | [`/v1/tiktok/videos/{video_id}`](/api-reference/endpoint/tiktok/get-video-detail) | GET | Full metadata for a single video | | [`/v1/tiktok/videos/{video_id}/comments`](/api-reference/endpoint/tiktok/get-comments) | GET | Top-level comments on a video | | [`/v1/tiktok/videos/{video_id}/related`](/api-reference/endpoint/tiktok/get-related-videos) | GET | Related/recommended videos | | [`/v1/tiktok/videos/{video_id}/transcript`](/api-reference/endpoint/tiktok/get-transcript) | GET | Subtitle tracks + voice-to-text | | [`/v1/tiktok/comments/{comment_id}/replies`](/api-reference/endpoint/tiktok/get-comment-replies) | GET | Replies to a comment | | [`/v1/tiktok/oembed`](/api-reference/endpoint/tiktok/get-oembed) | GET | Cheap unauthenticated oEmbed metadata | | [`/v1/tiktok/hashtags/{name}`](/api-reference/endpoint/tiktok/get-hashtag) | GET | Hashtag/challenge detail | | [`/v1/tiktok/hashtags/{name}/videos`](/api-reference/endpoint/tiktok/get-hashtag-videos) | GET | Videos tagged with a hashtag | | [`/v1/tiktok/music/{music_id}`](/api-reference/endpoint/tiktok/get-music) | GET | Sound/music detail | | [`/v1/tiktok/music/{music_id}/videos`](/api-reference/endpoint/tiktok/get-music-videos) | GET | Videos using a sound | | [`/v1/tiktok/search`](/api-reference/endpoint/tiktok/search) | GET | General Top-feed search | | [`/v1/tiktok/search/users`](/api-reference/endpoint/tiktok/search-users) | GET | Search users by keyword | | [`/v1/tiktok/search/videos`](/api-reference/endpoint/tiktok/search-videos) | GET | Search videos by keyword | | [`/v1/tiktok/search/hashtags`](/api-reference/endpoint/tiktok/search-hashtags) | GET | Search hashtags by keyword | | [`/v1/tiktok/trending/videos`](/api-reference/endpoint/tiktok/trending-videos) | GET | Trending Explore-feed videos | | [`/v1/tiktok/trending/hashtags`](/api-reference/endpoint/tiktok/trending-hashtags) | GET | Trending hashtags by usage | | [`/v1/tiktok/trending/songs`](/api-reference/endpoint/tiktok/trending-songs) | GET | Trending songs/sounds by usage | | [`/v1/tiktok/shop/bestsellers`](/api-reference/endpoint/tiktok/shop-bestsellers) | GET | Sales-ranked best-selling products (every operating market) | | [`/v1/tiktok/shop/categories`](/api-reference/endpoint/tiktok/shop-categories) | GET | TikTok Shop root categories (US, GB, ID) | | [`/v1/tiktok/shop/categories/{category_id}`](/api-reference/endpoint/tiktok/shop-category) | GET | Subcategories + top products of a category | | [`/v1/tiktok/shop/search`](/api-reference/endpoint/tiktok/shop-search) | GET | Keyword product search (US offset; SG/MY/PH/TH/VN/ID/JP native, token-paginated) | | [`/v1/tiktok/shop/mall`](/api-reference/endpoint/tiktok/shop-mall) | GET | Japan mall recommendations and navigation with cursor pagination | | [`/v1/tiktok/shop/stores/{seller_id}`](/api-reference/endpoint/tiktok/shop-store) | GET | Store stats + cursor-paginated catalogue | | [`/v1/tiktok/shop/products/{product_id}`](/api-reference/endpoint/tiktok/shop-product) | GET | Product detail: SKUs, prices, first reviews, shop | | [`/v1/tiktok/shop/products/{product_id}/reviews`](/api-reference/endpoint/tiktok/shop-reviews) | GET | Paginated reviews with rating breakdown | | [`/v1/tiktok/ads/search`](/api-reference/endpoint/tiktok/search-ads) | GET | Search the EU ad library | | [`/v1/tiktok/ads/advertisers`](/api-reference/endpoint/tiktok/search-advertisers) | GET | Look up advertiser business ids by name | | [`/v1/tiktok/ads/{ad_id}`](/api-reference/endpoint/tiktok/get-ad-detail) | GET | Single-ad detail: advertiser + targeting/impression breakdown | | [`/v1/tiktok/regions`](/api-reference/endpoint/tiktok/list-regions) | GET | List supported regions | **TikTok Shop market coverage** — `US`, `GB` and `ID` (Tokopedia) are served for product detail, categories, search and best-sellers. The Southeast Asian markets `SG`, `MY`, `PH`, `TH`, `VN` and `JP` are supported via native in-region signing for search, best-sellers and product detail, each in its local currency. **Taiwan (`region=TW`)** returns HTTP 200 with `availability: "not_operated"` and empty results on every Shop endpoint — TikTok operates no Shop marketplace there. ## Credit Costs | Endpoint | Cost | | - | - | | Get user profile | 5 credits | | Get user videos | 8 credits | | Get user reposts | 8 credits | | Get video detail | 5 credits | | Get comments | 8 credits | | Get related videos | 8 credits | | Get transcript | 10 credits | | Get comment replies | 8 credits | | oEmbed | 2 credits | | Get hashtag detail | 5 credits | | Get hashtag videos | 8 credits | | Get music detail | 5 credits | | Get music videos | 8 credits | | Search (general) | 5 credits | | Search users | 5 credits | | Search videos | 5 credits | | Search hashtags | 5 credits | | Trending videos | 5 credits | | Trending hashtags | 5 credits | | Trending songs | 5 credits | | Shop root categories | 5 credits | | Shop category products | 5 credits | | Shop search (per page) | 5 credits | | Shop mall (per page) | 5 credits | | Shop store (per page) | 5 credits | | Shop product detail | 8 credits | | Shop product reviews (per page) | 5 credits | | Ad library search | 5 credits | | Search advertisers | 5 credits | | Get ad detail | 8 credits | | List regions | 0 credits | | Failed requests | 0 credits | ## Authentication All requests require your API key in the `x-api-key` header: ```bash theme={null} curl "https://scrapebadger.com/v1/tiktok/users/charlidamelio" \ -H "x-api-key: YOUR_API_KEY" ``` ## Anti-Bot Handling & Notes TikTok protects its mobile and web APIs with request signing (X-Argus / X-Ladon / X-Gorgon / X-Khronos), device trust, and per-IP reputation scoring. ScrapeBadger clears these automatically — you never need to manage signatures, device registration, proxies, or sessions. Requests are routed through proxies matched to the `region` you request. **Trending hashtags and trending songs** (`/v1/tiktok/trending/hashtags`, `/v1/tiktok/trending/songs`) are served via an **mobile signer path**. They are ranked by real usage (view counts, distinct-creator counts) rather than the deprecated Creative Center trend lists. Public followers, following and liked lists use account-free guest requests. TikTok can expose only a subset; hidden/private data returns 403 and temporary upstream failures return 503. ## Next Steps Full API reference for fetching a TikTok user profile Retrieve full metadata for a specific TikTok video *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by TikTok. "TikTok" is a trademark of TikTok Ltd. (a ByteDance company), used here only to describe the platform this scraper is designed to work with.* ## Guest access and pagination Public content uses guest web and mobile providers; you do not need a TikTok account. Public followers/following and reposts support pagination. Liked lists are available only when the profile exposes them publicly. Hidden/private data returns 403, temporarily unavailable data returns 503, and an expired continuation cursor returns 410. Pass cursors unchanged with the same resource and region; guest continuation state lasts up to 15 minutes and expires when its guest session is replaced or the service restarts. Social lists reflect the subset TikTok exposes to that guest; they are not a guaranteed complete follower export. Web and mobile responses share the documented models, but optional native-only fields may be null. A populated metadata response does not guarantee that a media URL is downloadable: TikTok may reject even a fresh CDN URL with 403. Media links are upstream references, not a guaranteed download service. Mobile hashtag/song recommendations are not historical Creative Center rankings: omit `period`; only US is currently verified. For video downloads, fetch video detail and use its matching `video.video.media_headers` with `play_addr` or `download_addr`. These anonymous CDN headers are optional: null means usable media authorization was not obtained. Refresh detail when links expire. # Filter Rules Source: https://docs.scrapebadger.com/twitter-streams/filter-rules Monitor Twitter search queries in real-time # Filter Rules Filter Rules monitor arbitrary Twitter search queries using Advanced Search syntax. Each rule polls independently at a configurable interval, from sub-second (0.1s) to daily (86,400s). ## Quick start ```bash theme={null} # Create a filter rule curl -X POST "https://scrapebadger.com/v1/twitter/stream/filter-rules" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "tag": "AI News", "query": "\"artificial intelligence\" OR \"machine learning\" lang:en -is:retweet", "interval_seconds": 5, "webhook_url": "https://example.com/webhooks/tweets" }' ``` ## Features * **Up to 50 rules** per API key * **Advanced Search syntax** -- use `from:`, `to:`, `lang:`, `is:reply`, `has:media`, and more * **Configurable polling interval** from 0.1s to 86,400s * **Up to 100 results per poll** * **Webhook + WebSocket delivery** * **Query validation** endpoint to check syntax before creating ## Interval pricing tiers Faster polling intervals cost more credits per day: | Tier | Max Interval | Credits / rule / day | | - | - | - | | Turbo | 0.5s | 30,000 | | Fast | 5s | 10,000 | | Standard | 60s | 1,500 | | Relaxed | 600s (10min) | 500 | | Daily | 86,400s (24h) | 100 | Fetch current pricing dynamically via the [pricing tiers endpoint](/api-reference/endpoint/filter-rules/get-filter-rule-pricing). ## Query syntax examples | Query | Description | | - | - | | `from:elonmusk` | Tweets from a specific user | | `"breaking news" lang:en` | English tweets containing exact phrase | | `#bitcoin -is:retweet` | Original tweets with hashtag (no retweets) | | `to:OpenAI has:media` | Replies to OpenAI that contain media | | `from:elonmusk OR from:sataborasu` | Tweets from either user | ## Rule lifecycle 1. **Active** -- Rule is polling and delivering matched tweets 2. **Paused** -- Manually paused via API or dashboard 3. **Suspended** -- Auto-paused due to insufficient credits ## Deduplication Filter rules automatically deduplicate tweets. If the same tweet matches across multiple polls, it is delivered only once. ## API endpoints POST /v1/twitter/stream/filter-rules GET /v1/twitter/stream/filter-rules GET /v1/twitter/stream/filter-rules/ PATCH /v1/twitter/stream/filter-rules/ DELETE /v1/twitter/stream/filter-rules/ POST /v1/twitter/stream/filter-rules/validate GET /v1/twitter/stream/filter-rules-pricing # Stream Monitors Source: https://docs.scrapebadger.com/twitter-streams/monitors Monitor specific Twitter accounts in real-time # Stream Monitors Stream Monitors watch specific Twitter accounts and notify you when they tweet, reply, retweet, or quote tweet. Monitors poll at a global interval (100ms default) with volume-based pricing. ## Quick start ```bash theme={null} # Create a monitor curl -X POST "https://scrapebadger.com/v1/twitter/stream/monitors" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Tech Leaders", "usernames": ["elonmusk", "sataborasu"], "webhook_url": "https://example.com/webhooks/tweets", "filter_types": ["original", "reply"] }' ``` ## Features * **Up to 100 accounts** per monitor * **Tweet type filtering**: original, reply, retweet, quote * **Webhook delivery** with HMAC-SHA256 signing * **WebSocket delivery** for real-time streaming * **Auto-pause** when credits run low * **Volume pricing** -- the more accounts you monitor, the lower the per-account cost ## Volume pricing tiers | Tier | Accounts | Credits / account / day | | - | - | - | | Starter | 1--10 | 1,667 | | Growth | 11--50 | 1,333 | | Scale | 51--100 | 1,000 | | Enterprise | 101+ | 833 | Pricing tiers are applied per-monitor based on the number of usernames. Pricing can be fetched dynamically via the [dashboard stream pricing endpoint](/api-reference/endpoint/streams/get-stream-monitors). ## Monitor lifecycle 1. **Active** -- Monitor is polling and delivering tweets 2. **Paused** -- Manually paused via API or dashboard 3. **Suspended** -- Auto-paused due to insufficient credits (`status_reason: "insufficient_credits"`) ## Shadow account warning Newly registered or long-dormant Twitter accounts may be shadow-banned, causing searches to return no results. Before adding a username to a monitor, verify it is not shadow-banned: Visit `https://x.com/search?q=from:USERNAME&src=typed_query&f=live` -- if it returns no results for an active poster, the account is likely shadow-banned. ## API endpoints POST /v1/twitter/stream/monitors GET /v1/twitter/stream/monitors GET /v1/twitter/stream/monitors/ PATCH /v1/twitter/stream/monitors/ DELETE /v1/twitter/stream/monitors/ # Twitter Streams Overview Source: https://docs.scrapebadger.com/twitter-streams/overview Real-time Twitter monitoring with Stream Monitors and Filter Rules # Twitter Streams Monitor Twitter in real-time with two complementary approaches: * **Stream Monitors** -- Watch specific Twitter accounts and get notified when they tweet, reply, retweet, or quote. * **Filter Rules** -- Monitor arbitrary Twitter search queries using Advanced Search syntax. Both deliver tweets via **WebSocket** and/or **Webhook** with sub-second latency. ## Quick comparison | Feature | Stream Monitors | Filter Rules | | - | - | - | | **What it watches** | Specific accounts (by username) | Search queries (Advanced Search syntax) | | **Billing** | Per-account-per-day (volume tiers) | Per-rule-per-day (interval tiers) | | **Max per API key** | 100 accounts per monitor | 50 rules | | **Delivery** | WebSocket + Webhook | WebSocket + Webhook | | **Polling interval** | Global (100ms default) | Configurable per rule (0.1s -- 86400s) | ## How it works 1. **Create** a monitor or filter rule via the API (or dashboard) 2. **Configure delivery** -- attach a webhook URL and/or connect via WebSocket 3. **Receive tweets** in real-time as they are detected 4. **Credits are billed** automatically every 60 seconds based on your active monitors/rules ## Delivery methods ### WebSocket Connect to `wss://scrapebadger.com/v1/twitter/stream` with your API key to receive real-time tweet events. ```bash theme={null} wscat -c "wss://scrapebadger.com/v1/twitter/stream?api_key=YOUR_API_KEY" ``` Each message is a JSON object containing the tweet data, monitor/rule metadata, and timing information. ### Webhooks Configure an HTTPS webhook URL on your monitor or filter rule. ScrapeBadger sends an HTTP POST for each detected tweet, signed with HMAC-SHA256 so you can verify authenticity. ``` POST https://your-server.com/webhooks/tweets X-Signature-256: sha256=... Content-Type: application/json { "event": "tweet.detected", "monitor_id": "...", "tweet": { ... } } ``` ## Auto-pause on low balance When your credit balance drops below the estimated hourly cost, active monitors and filter rules are automatically paused with `status_reason: "insufficient_credits"`. They resume automatically when you top up. ## Next steps Monitor specific Twitter accounts Monitor search queries Real-time WebSocket delivery HTTP POST delivery with HMAC signing # Webhook Delivery Source: https://docs.scrapebadger.com/twitter-streams/webhooks Receive HMAC-SHA256 signed HTTP callbacks for detected tweets # Webhook Delivery Configure HTTPS webhook URLs on your stream monitors or filter rules to receive HTTP POST callbacks for each detected tweet. All webhooks are signed with HMAC-SHA256. ## Setup Set `webhook_url` when creating a monitor or filter rule: ```bash theme={null} curl -X POST "https://scrapebadger.com/v1/twitter/stream/monitors" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "My Monitor", "usernames": ["elonmusk"], "webhook_url": "https://example.com/webhooks/tweets", "webhook_secret": "my-secret-key" }' ``` If you omit `webhook_secret`, one is auto-generated and returned in the response. ## Webhook payload ```http theme={null} POST https://example.com/webhooks/tweets Content-Type: application/json X-Signature-256: sha256=a1b2c3d4... X-Webhook-Id: wh_abc123 X-Delivery-Id: del_xyz789 { "event": "tweet.detected", "monitor_id": "abc-123", "monitor_name": "My Monitor", "tweet_id": "1234567890", "author_username": "elonmusk", "tweet_text": "Just announced...", "tweet_url": "https://x.com/elonmusk/status/1234567890", "tweet_published_at": "2026-03-13T12:00:00Z", "detected_at": "2026-03-13T12:00:00.150Z", "latency_ms": 150, "tweet_data": { "id": "1234567890", "text": "Just announced...", "user": { ... }, "media": [ ... ] } } ``` ## Signature verification Every webhook includes an `X-Signature-256` header. Verify it to ensure the request is from ScrapeBadger: ### Python ```python theme={null} import hmac import hashlib def verify_signature(payload: bytes, signature: str, secret: str) -> bool: expected = "sha256=" + hmac.new( secret.encode(), payload, hashlib.sha256 ).hexdigest() return hmac.compare_digest(expected, signature) ``` ### Node.js ```javascript theme={null} const crypto = require('crypto'); function verifySignature(payload, signature, secret) { const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(payload).digest('hex'); return crypto.timingSafeEqual( Buffer.from(expected), Buffer.from(signature) ); } ``` ## Retry behavior * ScrapeBadger expects a **2xx response** within **10 seconds** * Failed deliveries are retried up to **3 times** with exponential backoff * Delivery status is visible in the [delivery logs endpoint](/api-reference/endpoint/streams/list-delivery-logs) ## Testing webhooks Use the test endpoint to send a sample payload to your webhook URL: ```bash theme={null} curl -X POST "https://scrapebadger.com/v1/twitter/stream/webhooks/test" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"monitor_id": "your-monitor-id"}' ``` ## Managing webhooks You can also manage webhooks separately from monitors using the dedicated webhook endpoints: POST /v1/twitter/stream/webhooks GET /v1/twitter/stream/webhooks DELETE /v1/twitter/stream/webhooks/ POST /v1/twitter/stream/webhooks/test # WebSocket Delivery Source: https://docs.scrapebadger.com/twitter-streams/websocket Connect via WebSocket for real-time tweet streaming # WebSocket Delivery Connect to the ScrapeBadger WebSocket endpoint to receive real-time tweet events from all your active stream monitors and filter rules. ## Connection ``` wss://scrapebadger.com/v1/twitter/stream?api_key=YOUR_API_KEY ``` ### Using wscat ```bash theme={null} npm install -g wscat wscat -c "wss://scrapebadger.com/v1/twitter/stream?api_key=YOUR_API_KEY" ``` ### Using Python ```python theme={null} import asyncio import websockets import json async def listen(): uri = "wss://scrapebadger.com/v1/twitter/stream?api_key=YOUR_API_KEY" async with websockets.connect(uri) as ws: async for message in ws: event = json.loads(message) print(f"New tweet from @{event['author_username']}: {event['tweet_url']}") asyncio.run(listen()) ``` ### Using Node.js ```javascript theme={null} const WebSocket = require('ws'); const ws = new WebSocket( 'wss://scrapebadger.com/v1/twitter/stream?api_key=YOUR_API_KEY' ); ws.on('message', (data) => { const event = JSON.parse(data); console.log(`New tweet from @${event.author_username}: ${event.tweet_url}`); }); ws.on('error', console.error); ``` ## Event format Each WebSocket message is a JSON object: ```json theme={null} { "event": "tweet.detected", "monitor_id": "abc-123", "monitor_name": "Tech Leaders", "tweet_id": "1234567890", "author_username": "elonmusk", "tweet_text": "Just announced...", "tweet_url": "https://x.com/elonmusk/status/1234567890", "tweet_published_at": "2026-03-13T12:00:00Z", "detected_at": "2026-03-13T12:00:00.150Z", "latency_ms": 150 } ``` ## Connection behavior * **Authentication** is done via the `api_key` query parameter * **Heartbeat pings** are sent every 30 seconds to keep the connection alive * **Auto-reconnect** is recommended in your client code -- the server may close idle connections * **All monitors and filter rules** for the API key deliver to the same WebSocket connection * **Multiple connections** are supported per API key ## Best practices 1. **Always implement reconnection logic** with exponential backoff 2. **Process messages asynchronously** to avoid blocking the WebSocket receive loop 3. **Use webhooks as a backup** -- WebSocket connections can drop, but webhooks retry delivery # Vinted Image Search Source: https://docs.scrapebadger.com/vinted/image-search Find visually similar active Vinted listings from an image URL, base64 photo or local file. `POST /v1/vinted/search_by_image` runs Vinted's native image search and returns ordinary active listings with prices, photos and URLs. No Vinted login is needed. A successful request costs **10 credits**; failed requests are free. ## Image input Supply exactly one of: * `image_url`: a public HTTP(S) URL that returns an image. * `image_base64`: the image encoded as base64, either a bare payload or a `data:image/jpeg;base64,...` URL. JPEG, PNG and WebP are supported, up to **5 MiB decoded**. Use a clear photo of one item. The [playground](https://scrapebadger.com/dashboard/vinted-scraper?utm_source=docs\&utm_medium=referral) also accepts a local file under **Search → Search by Image**. ```bash theme={null} curl 'https://scrapebadger.com/v1/vinted/search_by_image' \ -H 'X-API-Key: YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{"image_url":"https://example.com/photo.jpg","market":"nl","price_to":50,"per_page":20}' ``` Replace the example URL with your photo. An inaccessible URL, malformed base64, unsupported image or oversized decoded image returns an error, not a text-search fallback. Invalid parameter combinations return 422; invalid image input returns 400; an upstream failure returns 502. ## Filters | Parameter | Meaning | | - | - | | `market` | Market code, default `fr`; `uk` aliases `gb` | | `brand_ids`, `catalog_ids`, `status_ids` | Brand, category and condition IDs | | `color_ids`, `size_ids`, `material_ids` | Color, size and material IDs | | `price_from`, `price_to` | Nonnegative bounds in the selected market's currency | | `page`, `per_page` | Page number and page size (1–96; default 20) | | `time`, `search_session_id` | Pagination time and a consistent search session | Send ID filters as comma-separated positive integers, such as `"53,14"`. Image search uses Vinted's visual ranking; it has no `order` or `query` parameter. Resend the same image with the next page and the preceding response's `pagination.time`. Image search does not offer seller-country enrichment. ## Clients Use Python/Node SDK **0.47.0+** or CLI **0.15.0+**. ```python Python theme={null} import asyncio from scrapebadger import ScrapeBadger async def main(): async with ScrapeBadger(api_key="YOUR_API_KEY") as client: result = await client.vinted.search_by_image(payload={ "image_url": "https://example.com/photo.jpg", "market": "nl", "price_to": 50, }) print(result["items"]) asyncio.run(main()) ``` ```javascript Node.js theme={null} import ScrapeBadger from "scrapebadger"; const client = new ScrapeBadger({ apiKey: "YOUR_API_KEY" }); const result = await client.vinted.searchByImage({ image_url: "https://example.com/photo.jpg", market: "nl", price_to: 50, }); console.log(result.items); ``` ```bash CLI theme={null} scrapebadger vinted search-by-image --image photo.jpg --market nl --price-to 50 scrapebadger vinted search-by-image --image-url https://example.com/photo.webp --brand-ids 53 ``` ```json MCP theme={null} { "name": "vinted_search_by_image", "arguments": { "image_url": "https://example.com/photo.jpg", "market": "nl", "price_to": 50 } } ``` ## Results and limits The response uses the same `items`, `pagination` and `market` envelope as text search. Prices, photos, listing URLs and available size/condition labels are included. Structured `brand_title` may be null; `display_title` is a display label, not a guaranteed brand identifier. Each item carries a `similarity_score`: Vinted's own measure of visual similarity to the query image. Vinted returns a ranking on only some calls; on the rest `similarity_score` is `null` on every item. A `null` says nothing about the item — only that Vinted sent no score — so do not treat a missing score as a weak match. Filter on the score when it is present, and fall back to your own ranking when it is not. **The score is ordinal, not absolute.** It sits on an unbounded, undocumented scale that Vinted changes without notice — it read `0`–`1` in September 2026 and roughly `36`–`44` afterwards. Rank items against the others in the **same** response; never compare a score to a fixed threshold, and never compare scores between two responses. Whether a given photo gets scored is close to fixed for that photo within a session — repeated calls on one image tend to be all scored or all unscored — so retrying to obtain a score is not worth the credits. An unscored response is billed the same as a scored one. Searching with a listing's own photo usually returns that listing at or near the top, but nothing guarantees it is first. Drop it by `id` before computing a median, or it will bias the result toward its own asking price. The result set is largely but not perfectly stable across repeated calls on the same photo. These are **active asking prices**, not completed sale prices. For valuation, combine the matching listings with [sold comparables and price suggestions](/vinted/mobile-api). # Vinted mobile data Source: https://docs.scrapebadger.com/vinted/mobile-api Read listings, seller reviews, sold comparables, prices, categories, shipping references and help data through 76 public operations. The Vinted API now uses mobile JSON requests for search, item details, seller profiles, wardrobes, brands, colors and conditions. You do not need a Vinted account. The existing endpoints keep their response envelopes and pricing. For the wider data set, use **76 public read operations**. These include sold comparables, suggested prices, reviews, followers, related listings, category trees, homepage feeds, ISBN metadata, package sizes, and help articles. ## Discover operations ```bash theme={null} curl 'https://scrapebadger.com/v1/vinted/mobile/operations' \ -H 'X-API-Key: YOUR_API_KEY' ``` Discovery is free. Each entry includes its name, parameter types, required fields, example request parameters and expected response keys. The first data field is the primary result; additional configuration fields can vary by region. The playground loads this same catalog and provides a form for each operation. ## Read data All operation calls use `POST /v1/vinted/mobile/{operation}` with a JSON body: ```json theme={null} { "market": "fr", "parameters": { "catalog_id": "1242", "brand_id": "53", "status_id": "2" } } ``` For example, retrieve comparable sold listings: ```bash theme={null} curl 'https://scrapebadger.com/v1/vinted/mobile/sold-comparables' \ -H 'X-API-Key: YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{"market":"fr","parameters":{"catalog_id":"1242","brand_id":"53","status_id":"2"}}' ``` The response contains `operation`, `market`, and the upstream JSON in `data`. Each successful read costs **1 credit**. Failed requests are free. An empty collection can be a valid result; the operation description identifies inputs that returned empty or limited data during validation. Sold comparables are a sample of similar sold listings, not an exhaustive sales history. Their prices are not guaranteed final negotiated settlement prices. The `price-suggestions` operation returns Vinted's suggested price and range. ## CLI and MCP CLI version 0.14.0 or later: ```bash theme={null} scrapebadger vinted mobile-operations scrapebadger vinted mobile sold-comparables --market fr \ --params '{"catalog_id":"1242","brand_id":"53","status_id":"2"}' scrapebadger vinted mobile user-feedback --market pl \ --params '{"user_id":94118559,"per_page":3}' ``` MCP clients use `vinted_mobile_operations` to discover inputs, then `vinted_mobile_read` with `operation`, `market`, and `parameters`. Existing Vinted MCP tools remain available. ## Search and field changes * `/v1/vinted/search` also accepts `size_ids`, `material_ids`, `time`, and `search_session_id`. Reuse the returned pagination `time` and your search session across pages. Live results can overlap; deduplicate by item ID. * `market` selects the locale and catalog region. It does not limit listings to sellers physically located in that country. Use the existing `seller_country` filter on `/search` when you need that restriction. Core reads use the requested country so prices and region-specific wardrobes match that market. * Search URLs are absolute. `display_title` and `display_subtitle` retain Vinted's presentation labels. `brand_title` is null when the response does not provide a reliable brand field; a display label can include a model name. * Item details return descriptions, brand/category/condition IDs and photos. Unavailable fields remain null. A size-guide or condition FAQ link ID is not an item attribute ID. * These operations read public data. They do not perform purchases, payments, messages, account changes or listing publication. ## Operation catalog The tables below list every operation. Use discovery for full parameter types, optional fields and runnable examples. Parameters belong inside `parameters`, including identifiers used to select an item, seller or category. ### Discovery | Operation | Required parameters | Result | | - | - | - | | `catalog-search` | None | `items` (plus estimated listing times), `pagination`, `search_tracking_params`, `uploaded_at_reference` | | `filters` | None | `filters`, `selected_filters` | | `filter-facets` | `filter_code` | `filter_code`, `options`, `total_count`, `total_count_max` | | `filter-search` | `filter_search_code`, `filter_search_text` | `is_selection_highlighted`, `options`, `selected_filters` | | `categories` | None | `catalogs` | | `suggestions` | `search_text` | `results` | | `homepage-configuration` | None | `homepage_session_id`, `staggered_homepage_enabled`, `verticals` | | `homepage` | `vertical`, `column_count`, `version` | `blocks`, `load_more_button`, `pagination` | | `promoted-closets` | None | `page_info`, `promoted_closets` | ### Listing age on catalog search Vinted sends no upload time on search results. `catalog-search` adds an estimate to every item, at the same 1 credit: | Field | Meaning | | - | - | | `estimated_uploaded_at` | ISO 8601 UTC time the listing went live, or `null` when it cannot be estimated. | | `estimated_uploaded_at_source` | `photo_stamp`: the item's own measured photo stamp, the same value `item-details` returns as `uploaded_at`. `item_id`: an estimate from the item ID. | | `estimated_uploaded_at_bracket_seconds` | For `item_id` estimates: the time between the nearest listings with a known time on either side of this ID. This is what predicts the error. `null` for `photo_stamp`. | Vinted's item IDs are one global sequence across markets, so an ID can be placed between listings whose times we know. Those reference times come from the photo stamps of item-details responses, including a listing we read every few minutes to keep the most recent IDs covered. The error depends on how close those references are: | `bracket_seconds` | Error against the photo stamp, 90% of listings | | - | - | | under 1,800 (30 min) | within 5 minutes | | 1,800 to 10,800 | within about 3 hours | | over 10,800 | hours to days, so do not rely on it for fine-grained age | About 1% of listings are off by more than a day even with close references. These are drafts published later or relisted items, whose ID is older than the moment they went live. An item older than every reference comes back `null`. An item newer than every reference is placed between the newest reference and the time of the response. Each response also carries `uploaded_at_reference`, which tells you how far back the estimates reach: ```json theme={null} "uploaded_at_reference": { "anchors": 98412, "oldest_anchor_at": "2026-09-27T08:14:02Z", "newest_anchor_at": "2026-10-07T13:28:28Z" } ``` It is `null` if the reference table is briefly unavailable, in which case every estimate is `null` too and the search itself still succeeds. ### Items | Operation | Required parameters | Result | | - | - | - | | `item-services` | `item_id` | `original_asking_amount`, `seller_original_asking_amount`, `services`, `total_amount` | | `item-details` | `item_id` | `item` (plus `item.uploaded_at`), `plugins` | | `item-photos` | `item_id` | `photos` | | `public-photos` | `item_ids[]`, `photo_size` | `photos` | | `item-translatable` | `item_id` | `plugins` | | `related-items` | `item_id`, `content_source` | `items`, `title`, `next_page_token` | | `item-shipping` | `item_id` | `shipping_details` | | `item-share` | `item_id` | `share_url` | `item-details` returns Vinted's payload unchanged except for one field we add: `item.uploaded_at`, an ISO 8601 UTC timestamp taken from the earliest photo upload. It is approximate in both directions. A seller who replaces a photo after listing moves it later, and a photo uploaded before the listing is published can predate it by about 30 minutes. Related items carry no upload time. `related-items` takes `content_source` `similar_items` or `other_user_items`. To get the next page, send the previous response's `next_page_token`. When it is `null` there are no more pages. ### Sellers | Operation | Required parameters | Result | | - | - | - | | `user-profile` | `id` | `user` | | `user-search` | None | `users`, `pagination` | | `user-items` | `user_id` | `items`, `pagination` | | `user-followers` | `user_id` | `users`, `pagination` | | `user-following` | `user_id` | `users`, `pagination` | | `user-categories` | `user_id` | `catalogs` | | `user-feedback` | `user_id` | `user_feedbacks`, `pagination` | | `user-feedback-summary` | `user_id` | `user_feedback_summary` | | `seller-badges` | `sellerID`, `timeZone` | `badges` | ### Reference | Operation | Required parameters | Result | | - | - | - | | `brands` | `keyword` | `brands`, `pagination` | | `brand-suggestions` | None | `brands`, `pagination` | | `size-groups` | `catalog_ids[]` | `size_groups` | | `catalog-filters` | None | `filters`, `selected_filters` | | `catalog-filter-facets` | `filter_code` | `filter_code`, `total_count`, `total_count_max` | | `catalog-filter-search` | `filter_search_code`, `filter_search_text` | `options`, `is_selection_highlighted`, `selected_filters` | | `wardrobe-categories` | None | `catalogs` | | `seller-filters` | None | `filters` | | `upload-categories` | None | `catalogs` | | `upload-category-search` | `keyword` | `catalog_ids` | | `upload-brands` | `keyword` | `brands`, `disable_custom_brands` | | `colors` | None | `colors` | | `book-isbn` | `isbn` | `isbn_records`, `attributes` | | `book-isbn-validate` | `isbn` | Success acknowledgement | | `upload-configuration` | None | `catalog_group_fields`, `max_custom_shipping_price`, `ab_tests`, `upload_session_id`, `currency`, `photo_tip`, `price_range`, `is_first_time_lister`, `category_suggestions_photo_count`, `attribute_suggestions_photo_count`, `suggestions_configuration`, `number_of_images_per_item`, `image_resizing`, `professional_seller_key`, `measurements`, `package_size_defining_item_attribute_codes_abTest` | | `upload-models` | `catalog_id`, `brand_id` | `sorting_type`, `models`, `pagination`, `disable_unknown_models` | | `upload-model-search` | `catalog_id`, `brand_id`, `search_text` | `models`, `disable_unknown_models` | | `authenticity-info` | `catalog_id` | `authenticity_modal` | | `photo-tips` | None | `photo_tips` | | `upload-banners` | `category_id` | `extra_section_banners` | | `countries` | None | `countries` | | `country-languages` | `country_id` | `languages`, `primary_language`, `country` | | `country-cities` | `country_id` | `cities` | | `nationalities` | None | `countries`, `suggested_countries` | | `languages` | None | `languages`, `country` | | `recommended-locale` | None | `recommended_locale`, `recommended_iso_locale` | | `upload-attributes` | `attributes` | `attributes` | | `upload-attribute-search` | `code`, `value` | `options` | ### Shipping | Operation | Required parameters | Result | | - | - | - | | `category-package-sizes` | `catalog_id` | `package_sizes`, `parcel_measurements`, `xs_package_size_experiment_eligible`, `heavy_small_package_size_experiment_eligible` | | `bundle-package-sizes` | `item_ids[]` | `package_sizes`, `parcel_measurements` | | `largest-shipping-rates` | None | `shipping_rates` | ### Help | Operation | Required parameters | Result | | - | - | - | | `help-tree` | `country`, `language` | `faq_entries`, `faq_entries_parent_code`, `faq_entries_parent_id`, `faq_entries_parent_title` | | `help-entry` | `faq_entry_id`, `country`, `language` | `faq_entry` | | `help-entry-core` | `faq_entry_id` | `faq_entry` | | `help-feedback-options` | `faq_entry_id` | `feedback_uuid`, `feedback_ratings` | | `terms` | None | `terms_and_conditions` | ### Configuration | Operation | Required parameters | Result | | - | - | - | | `custom-shipment-configuration` | None | `custom_shipment_configuration` | | `session-defaults` | None | `session_defaults_configuration` | | `system-configuration` | None | `system_configuration` | | `features` | None | `features` | | `app-version` | None | `app_version` | | `ad-configuration` | None | `ads`, `partner_ids`, `reduce_ad_frequency` | | `consent-configuration` | None | `language_iso`, `cookie_consent_version` | | `ad-configuration-core` | None | `ads`, `reduce_ad_frequency` | | `consent-configuration-core` | None | `language_iso`, `cookie_consent_version` | | `banners` | None | `banners` | | `info-banners` | None | `info_banners` | | `catalog-banners` | None | Success acknowledgement | ### Pricing | Operation | Required parameters | Result | | - | - | - | | `price-suggestions` | `catalog_id`, `brand_id`, `status_id` | `price_suggestion`, `similar_sold_items_present` | | `sold-comparables` | `catalog_id`, `brand_id`, `status_id` | `items` | ## Python and Node SDKs Use SDK version 0.46.0 or newer. Python takes a `payload` keyword; Node takes the JSON body as its second argument. ```python theme={null} import asyncio from scrapebadger import ScrapeBadger async def main(): async with ScrapeBadger(api_key="YOUR_API_KEY") as client: operations = await client.vinted.list_public_vinted_mobile_operations() result = await client.vinted.read_vinted_mobile_data( "sold-comparables", payload={"market": "fr", "parameters": {"catalog_id": "1242", "brand_id": "53", "status_id": "2"}}, ) print(result) asyncio.run(main()) ``` ```typescript theme={null} import { ScrapeBadger } from "scrapebadger"; const client = new ScrapeBadger({ apiKey: "YOUR_API_KEY" }); const operations = await client.vinted.listPublicVintedMobileOperations(); const result = await client.vinted.readVintedMobileData("sold-comparables", { market: "fr", parameters: { catalog_id: "1242", brand_id: "53", status_id: "2" }, }); console.log(result); ``` # Vinted Scraper API — Overview Source: https://docs.scrapebadger.com/vinted/overview Search Vinted by text or photo, inspect listings and sellers, compare sold prices, and explore reference data. Search Vinted listings by **text or image**, inspect items and sellers, and compare sold listings and suggested prices. ScrapeBadger handles mobile authentication and market routing. You need a ScrapeBadger API key; no Vinted account is required. Supply a photo URL or upload an image to find similar active listings. Filter listings by category, brand, price, size, material, color and condition. Explore sold comparables, suggested prices, seller feedback and reference data. ## Explore the same sections as the playground The [Vinted playground](https://scrapebadger.com/dashboard/vinted-scraper?utm_source=docs\&utm_medium=referral) groups endpoints by what they do. All Vinted requests use the mobile transport. | Section | Entries | What you can do | | - | -: | - | | Search | 2 | Search active listings by text or image | | Items | 9 | Inspect listing details, photos, related items and item metadata | | Sellers | 11 | Read profiles, wardrobes, feedback and seller relationships | | Reference | 32 | Discover markets, brands, categories, colors, conditions and filters | | Discovery | 9 | Explore catalog results, navigation and discovery feeds | | Shipping | 3 | Read shipping reference information | | Help | 5 | Read help content and articles | | Configuration | 12 | Read public application and market configuration | | Pricing | 2 | Query sold comparables and suggested prices | The 85 entries include the normalized endpoints and 76 discoverable read operations. [Get the operation catalog](/api-reference/endpoint/vinted/mobile-operations) for current names, required parameters and runnable examples. Image search is a separate endpoint, not one of those 76 read operations. ## Quick start ```bash Text search theme={null} curl 'https://scrapebadger.com/v1/vinted/search?query=nike&market=nl&per_page=10' \ -H 'X-API-Key: YOUR_API_KEY' ``` ```bash Image search theme={null} curl 'https://scrapebadger.com/v1/vinted/search_by_image' \ -H 'X-API-Key: YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{"image_url":"https://example.com/photo.jpg","market":"nl","per_page":10}' ``` ```bash Sold comparables theme={null} curl 'https://scrapebadger.com/v1/vinted/mobile/sold-comparables' \ -H 'X-API-Key: YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{"market":"fr","parameters":{"catalog_id":"1242","brand_id":"53","status_id":"2"}}' ``` Replace the example image URL with a public JPEG, PNG or WebP photo. The [image-search guide](/vinted/image-search) covers base64, local files, filters, pagination, CLI, MCP and SDK usage. ## Choose a market `market` defaults to `fr`. Supported codes: `fr`, `de`, `es`, `it`, `nl`, `be`, `pt`, `pl`, `lt`, `cz`, `at`, `sk`, `hu`, `ro`, `lu`, `fi`, `dk`, `se`, `gb`, `lv`, `hr`, `ee`, `gr`, `ie`, `si`, `us`, `au`. `uk` is accepted as an alias for `gb`. [List markets](/api-reference/endpoint/vinted/list-markets) to get their domains, locales and currency codes. Market selects the catalog region and locale; it does not restrict the seller's physical country. European markets can contain listings from sellers across borders. Prices retain the market currency; ScrapeBadger does not perform currency conversion. Text search also supports `seller_country` to filter by seller location after retrieval. Its pagination totals describe the upstream results before that filter, so a returned page may contain fewer items than requested. ## Filters and pagination Both text and image search accept `brand_ids`, `catalog_ids`, `status_ids`, `color_ids`, `size_ids`, `material_ids`, `price_from`, `price_to`, `page` and `per_page` (1–96). IDs are comma-separated. Discover IDs in the reference endpoints or operation catalog. `catalog_ids` filters categories before retrieval. Text search accepts `order`; image search uses visual ranking. For subsequent pages, reuse `pagination.time` as `time` and keep `search_session_id` consistent. Image search also requires the same image source on each page. Deduplicate results by item ID because listings can change while you paginate. ## Response formats and field availability * Normalized search returns `items`, `pagination` and `market`. * Read operations return `operation`, `market` and upstream JSON under `data`. * Listing summaries include prices, URLs, photos, display labels and available size/condition information. Labels may be localized. * `brand_title` can be null when Vinted omits structured brand data. `display_title` is a display label; do not treat it as a reliable brand ID. * Image search supplies no similarity or confidence score. * Sold comparables are a sample of sold listings, not exhaustive history. Their displayed prices are not guaranteed final negotiated sale prices. ## Pricing | Request | Credits per success | | - | -: | | Text search | 5 | | Image search | 10 | | Item details | 10 | | Seller profile or wardrobe | 3 | | Brand search | 3 | | Colors or conditions | 1 | | Any `/mobile/{operation}` read | 1 | | Markets or operation discovery | 0 | Failed requests are free. Check `X-Credits-Used` for the billed amount and the [live pricing page](https://scrapebadger.com/vinted-scraper#pricing) for current rates. # Walmart Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/walmart/overview Search walmart.com, pull full product detail with UPC and specifications, paginate reviews with the complete star histogram, browse deals, and read marketplace sellers and physical stores — no Walmart API key required. ## Scraper API for Walmart The ScrapeBadger **Walmart API** turns `walmart.com` into a clean JSON feed: keyword search, category browse, a deals/rollback feed, full product detail (UPC/GTIN, structured specifications, per-fulfilment promised delivery dates, condition offers), paginated reviews with the complete star histogram, marketplace seller profiles and catalogues, and physical-store detail with per-department hours. All endpoints are `GET`, live under `https://scrapebadger.com/v1/walmart/*`, and authenticate with the `X-API-Key` header. Credits are charged per request (see the table below) and reported on the `X-Credits-Used` response header. ## Features * **Product search** — keywords with `sort`, price band and facet filters. \~40–60 organic products per page. Sponsored ad tiles are dropped; sponsored *products* are returned and flagged `is_sponsored`. * **Category browse** — any `walmart.com/browse/...` or `/cp/...` path, same result shape as search. * **Deals feed** — Walmart's live rollbacks and clearance as a paginated product feed, not a boolean on a product row. * **Full product detail** — `upc`/`gtin`, `model`, grouped `specification_groups[]`, `variants[]`, `condition_offers[]` (new vs pre-owned on the same item), `fulfillment_summary[]` with promised delivery dates per method, `return_policy`, `nutrition_facts` for grocery, plus a reviews sample so shallow use cases need only one call. * **Full review histogram** — `distribution` carries per-star **counts and percentages** (`five_star`, `five_star_percent`, …), `recommended_percentage` and `total_media_count`, alongside paginated review text. * **Marketplace sellers** — profile (contact, address, rating, policies) and a searchable catalogue of that seller's inventory. * **Physical stores** — a store's address, geo, phone, opening hours, **per-department services each with their own hours and phone**, fuel prices where present, and \~30 nearby stores in the same response. * **Walmart's generative-AI product content** — `ai_description_html` and `ai_highlights[]`, surfaced rather than trimmed. No competing Walmart API offers a store-detail, deals, or seller-catalogue endpoint — seller endpoints elsewhere return profile metadata only. ## Coverage **US only.** Only `walmart.com` is supported. | Code | Country | Currency | Language | Domain | | - | - | - | - | - | | `US` | United States | USD | en-US | walmart.com | `walmart.ca` and `walmart.com.mx` are **not supported**. They are different platforms with different payload shapes, not a locale switch on `walmart.com`, and are deliberately not claimed here rather than shipped broken. ## Credits | Endpoint | Path | Credits | | - | - | - | | Search products | `GET /v1/walmart/search` | 5 | | Browse a category | `GET /v1/walmart/category` | 5 | | Deals | `GET /v1/walmart/deals` | 5 | | Autocomplete | `GET /v1/walmart/autocomplete` | 1 | | Get product detail | `GET /v1/walmart/products/{item_id}` | 10 | | Get product reviews | `GET /v1/walmart/products/{item_id}/reviews` | 10 | | Get seller profile | `GET /v1/walmart/sellers/{seller_id}` | 5 | | Get seller products | `GET /v1/walmart/sellers/{seller_id}/products` | 5 | | Get store detail | `GET /v1/walmart/stores/{store_id}` | 5 | | List markets | `GET /v1/walmart/markets` | 0 | ## Quickstart ```bash cURL theme={null} curl "https://scrapebadger.com/v1/walmart/search?query=laptop&sort=price_low&max_price=500" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/walmart/search?" + new URLSearchParams({ query: "laptop", sort: "price_low", max_price: "500", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); console.log(data.items.length, "products"); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/walmart/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={ "query": "laptop", "sort": "price_low", "max_price": 500, }, ) print(len(res.json()["items"]), "products") ``` ## Pagination limits `total_results_reported` is **Walmart's own claim**, not a reachable count. A query reporting \~14,000 results stops returning products after **page 10** (`/search`, `/sellers/{id}/products`) or **page 11** (`/category`, `/deals`) — pages beyond that return HTTP 200 with an empty payload. That is roughly **500 products per query**. * Always page on **`has_more_pages`**, never on `total_results_reported`. * `max_page` in every result set is the measured ceiling for that surface. * To go deeper than 500, **segment the query**: repeat it per brand facet (`facet=brand:HP`) or across price bands (`min_price` / `max_price`). Consecutive pages **overlap by roughly 20%** — Walmart re-ranks between requests, so a product on page 2 may reappear on page 3. **Deduplicate on `us_item_id`** when collecting across pages. ## Store-specific prices Walmart resolves the assortment store from the **request IP**. It cannot be pinned by a parameter or cookie — the server overwrites any store id back to the IP default. Prices and availability are therefore store-specific whether you asked for it or not. Every product response carries a `location` block naming the store that was resolved, so the answer is always attributable: ```json theme={null} "location": { "postal_code": "95519", "city": "Mckinleyville", "state": "CA", "store_id": "5629", "intent": "SHIPPING" } ``` ## Other measured limits * **`/category` has no `sort`.** Walmart's browse pages ignore it (34/38 identical ids with and without it, and the param is not echoed back). Sort on `/search` instead. * **Facets can be applied but not enumerated.** Pass `facet=brand:HP` and it filters; there is no endpoint listing available facets, because Walmart renders the filter rail client-side. * **The seller id is the numeric `catalog_seller_id`** found on a product — *not* the 32-char hex `seller_id`, which 404s as a storefront URL. * **`/sellers/{id}` returns no product list.** The storefront grid is rendered client-side. Use [`/sellers/{id}/products`](/api-reference/endpoint/walmart/get-seller-products), which goes through search and therefore **requires a `query`**. * **Searching by UPC does not work.** Walmart returns zero results for a bare UPC — resolve UPCs by keyword and read `upc` off the product detail instead. * **Reviews are 10 per page.** That is Walmart's page size and is not adjustable. ## Errors | Status | Meaning | | - | - | | `404` | Item, seller or store does not exist (or has been removed). | | `422` | Anti-bot challenge — **not billed**. Retry; it succeeds. | Start from [`/autocomplete`](/api-reference/endpoint/walmart/autocomplete) (1 credit) to expand a partial term into real Walmart queries, then run [`/search`](/api-reference/endpoint/walmart/search) on each one and merge on `us_item_id` — cheaper coverage than paging one query into its page-10 wall. *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Walmart. "Walmart" is a trademark of Walmart Inc., used here only to describe the platform this scraper is designed to work with.* # Web Scraping Overview Source: https://docs.scrapebadger.com/web-scraping/overview Scrape any website with automatic anti-bot bypass, JavaScript rendering, and AI-powered data extraction. # Web Scraping API Scrape any public webpage and get back clean HTML, Markdown, or plain text. The API handles anti-bot protection, JavaScript rendering, and proxy rotation automatically. ## Key Features Automatically picks the best scraping approach for each site — from fast HTTP requests to full browser rendering. Detects and bypasses Cloudflare, DataDome, Akamai, Kasada, and other protection systems. Extract structured data from any page using natural language prompts powered by LLMs. Record browser sessions as animated GIFs for debugging, visual verification, and monitoring. Capture full-page PNG screenshots of any webpage. Route requests through proxies in 37+ countries to access location-specific content. ## How It Works 1. **Send a URL** to the `/v1/web/scrape` endpoint 2. **ScrapeBadger picks the best approach** — fast HTTP for simple pages, headless browser for JavaScript-heavy sites 3. **Anti-bot detection runs automatically** — if a block is detected, the request retries with more powerful methods 4. **Get clean content back** in your preferred format (HTML, Markdown, or plain text) ## Scraping Tiers ScrapeBadger uses a tiered system. When `engine` is set to `"auto"` (the default), the most cost-effective method is tried first and the system escalates automatically if needed. | Tier | Description | Cost | | - | - | - | | **HTTP** | Fast HTTP request with Chrome TLS fingerprint — works for most websites | 1 credit | | **Browser** | Full headless browser with JavaScript rendering — for SPAs and dynamic pages | 5 credits | | **Premium Browser** | Real browser with advanced fingerprinting — for heavily protected sites | 10 credits | ### Auto-Escalation When `escalate` is enabled, ScrapeBadger automatically tries more powerful methods if the initial one is blocked: ``` HTTP (1 credit) → Browser (5 credits) → Premium Browser (10 credits) ``` You only pay for the method that succeeds — escalation costs are **not cumulative**. ## Credit Costs Every request pays an **engine cost plus a `proxy_tier` surcharge**. The engine cost alone is never the total. | Component | Cost | | - | - | | HTTP engine — simple pages in `engine: auto` | 1 credit | | Browser engine — `render_js`, `anti_bot`, `video`, or auto-escalation | 5 credits | | Proxy tier `simple` (default) | +1 credit | | Proxy tier `premium` | +8 credits | | Proxy tier `ultra` | +8 credits | | AI extraction (`ai_extract: true`) | +10 credits | | Retries | Free | | Failed requests | 0 credits | The anti-bot solver and video recording are not billed on top — they force the browser engine, so they cost the 5-credit engine rate. Common totals: | Request | Total | | - | - | | HTTP page, `simple` proxy (cheapest possible scrape) | 2 credits | | Browser render, `simple` proxy | 6 credits | | HTTP page, `premium` proxy | 9 credits | | Browser render, `premium` proxy | 13 credits | Use the `max_cost` parameter to set a credit budget per request. The request will fail rather than exceed your budget. The exact charge is returned in `credits_used` and the `X-Credits-Used` response header. ## Caching `/v1/web/detect` caches its result per domain for **5 minutes**. A cached `detect` response is returned with status `200` and costs **0 credits** — handy when you probe the same domain repeatedly. To get a fresh detection within that window, wait for the 5-minute TTL to lapse. `/v1/web/scrape` does **not** cache page content: every scrape performs a fresh crawl and is billed for the engine that produced the result. There is no stale-content window to work around. ## Unsupported Sites Some sites with aggressive, account-gated bot detection are **not supported** and may return errors. In particular, walled social platforms such as **Facebook**, **Instagram**, and **LinkedIn** block automated access behind login and are out of scope for `/v1/web/scrape`. For supported social and marketplace data, use the dedicated source APIs (Twitter/X, Reddit, TikTok, YouTube, etc.). ## Quick Example ```bash cURL theme={null} curl -X POST "https://scrapebadger.com/v1/web/scrape" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://scrapebadger.com", "format": "markdown" }' ``` ```python Python theme={null} import requests response = requests.post( "https://scrapebadger.com/v1/web/scrape", headers={"x-api-key": "YOUR_API_KEY"}, json={ "url": "https://scrapebadger.com", "format": "markdown" } ) data = response.json() print(data["content"]) ``` ```javascript JavaScript theme={null} const response = await fetch("https://scrapebadger.com/v1/web/scrape", { method: "POST", headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ url: "https://scrapebadger.com", format: "markdown" }) }); const data = await response.json(); console.log(data.content); ``` ## Endpoints | Endpoint | Method | Description | | - | - | - | | [`/v1/web/scrape`](/api-reference/endpoint/web-scraping/scrape) | POST | Scrape a URL and return content | | [`/v1/web/detect`](/api-reference/endpoint/web-scraping/detect) | POST | Detect anti-bot and CAPTCHA systems on a URL | ## Next Steps Full API reference for the scrape endpoint Analyze a URL for anti-bot protection # Yahoo Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/yahoo/overview Search Yahoo's web SERP with organic results, ads and related searches, plus image, video and news search and query autocomplete — across 35 markets, no Yahoo API key required. ## Scraper API for Yahoo The ScrapeBadger **Yahoo API** turns `search.yahoo.com` into a clean JSON feed: the web SERP (organic results with resolved destination URLs, ads and related searches), image search with full-size URLs and dimensions, video search with duration and host platform, news search with publisher and syndication source, and search-box autocomplete. All endpoints are `GET`, live under `https://scrapebadger.com/v1/yahoo/*`, and authenticate with the `X-API-Key` header. Credits are charged per request (see the table below) and reported on the `X-Credits-Used` response header. ## Features * **Web SERP** — organic results with `position`, resolved destination `url` (Yahoo's redirect wrapper is decoded), `display_url` and `snippet`, plus `ads[]` and `related_searches[]`. * **Image search** — full-size `image_url`, `thumbnail_url`, the page the image lives on (`source_url` / `source_domain`) and pixel `width`/`height`. * **Video search** — title, thumbnail, `duration`, host platform (`source`, e.g. YouTube), `description` and `views`. * **News search** — headline, publisher, syndication source (`via`), thumbnail and Yahoo's reported total match count. * **Autocomplete** — Yahoo's search-box suggestions for 1 credit. * **SafeSearch control** — `safe_search=off|moderate|strict` on web search. ## Markets Yahoo localizes search through **regional subdomains** — `fr.search.yahoo.com`, `de.search.yahoo.com`, and so on — rather than a query parameter. Every endpoint takes a single lowercase `market` code (`us`, `uk`, `de`, `br`, …) that selects the subdomain. [`GET /v1/yahoo/markets`](/api-reference/endpoint/yahoo/list-markets) (free) returns all 35 supported codes with the search host each one maps to. **Yahoo Japan is not covered.** `search.yahoo.co.jp` is operated by a separate company running its own engine and page structure — it is not a Yahoo Search market and is deliberately excluded. ## Credits | Endpoint | Path | Credits | | - | - | - | | Web search | `GET /v1/yahoo/search` | 5 | | Image search | `GET /v1/yahoo/images` | 5 | | Video search | `GET /v1/yahoo/videos` | 5 | | News search | `GET /v1/yahoo/news` | 5 | | Autocomplete | `GET /v1/yahoo/autocomplete` | 1 | | List markets | `GET /v1/yahoo/markets` | 0 | ## Quickstart ```bash cURL theme={null} curl "https://scrapebadger.com/v1/yahoo/search?query=coffee+machine&market=uk" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/yahoo/search?" + new URLSearchParams({ query: "coffee machine", market: "uk", }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); console.log(data.result_count, "results returned"); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/yahoo/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "coffee machine", "market": "uk"}, ) data = res.json() print(data["result_count"], "results returned") ``` ## Pagination Yahoo serves **7 organic results per page** and has no page-size parameter. `offset` is a zero-based *absolute result offset*, so page 2 is `offset=7`, page 3 is `offset=14`, and so on. `/images` and `/videos` work differently: Yahoo renders roughly 60 tiles into the first response with no native page-size control, so `count` **trims that list client-side** rather than paginating. Values above what Yahoo rendered simply return everything available. ## Other notes * **Yahoo web search is Bing-syndicated.** Yahoo has not run its own web crawler for years — organic results come from Microsoft's index. Expect results close to, but not identical to, the [Bing API](/bing/overview): Yahoo applies its own ranking, ad load and page layout on top. * **News timestamps are relative only.** Yahoo News renders ages like `"26 minutes ago"` and no absolute date anywhere on the page, so `published` is that display string. There is no `published_at` or `published_utc` field — unlike the Bing news endpoint, which reads an RSS feed. Compute absolute times from your own request time if you need them. * **Images and videos are US-hosted.** Those verticals only exist in this form on `images.search.yahoo.com` / `video.search.yahoo.com`, so they are fetched from the fixed US hosts regardless of the `market` you pass. The `market` value is echoed back for consistency. * **Organic `url` values are final destinations.** Yahoo wraps results in a tracking redirect; the API resolves it so you get the real URL. * **`ads[]` and `related_searches[]`** appear only when Yahoo serves them for that query and market. ## Errors | Status | Meaning | | - | - | | `422` | Yahoo served a consent or challenge page instead of content — **not billed**. Retry; it succeeds. | | `502` | Unexpected upstream failure — **not billed**. | Start from [`/autocomplete`](/api-reference/endpoint/yahoo/autocomplete) (1 credit) to expand a seed term into real Yahoo queries, then run [`/search`](/api-reference/endpoint/yahoo/search) on each suggestion. *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Yahoo. "Yahoo" is a trademark of Yahoo Inc., used here only to describe the platform this scraper is designed to work with.* # Yandex Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/yandex/overview Search Yandex's web SERP with organic results, ads, inline images and videos, plus image search and reverse image search — across yandex.com.tr, .com, .ru, .by, .kz and .uz, no Yandex API key required. ## Scraper API for Yandex The ScrapeBadger **Yandex API** turns Yandex Search into a clean JSON feed: the web SERP (organic results with resolved destination URLs, ads, inline images and videos, related searches and pagination), text-query image search with full-resolution URLs and dimensions, and **reverse image search** by URL (hosting pages, similar images, detected tags and other sizes). All endpoints are `GET`, live under `https://scrapebadger.com/v1/yandex/*`, and authenticate with the `X-API-Key` header. Credits are charged per request (see the table below) and reported on the `X-Credits-Used` response header. ## Features * **Web SERP** — organic results with `position`, resolved destination `url` (Yandex's `/r?u=` redirects are decoded), `displayed_url`, `domain`, `snippet`, `favicon` and `sitelinks[]`, plus `ads[]`, `inline_images[]`, `inline_videos[]`, `related_searches[]`, an optional `knowledge_graph` and `pagination`. * **Image search** — full-resolution `image` (`url`, `width`, `height`), `thumbnail`, the page the image lives on (`source_url`) and `suggested_searches[]`. * **Reverse image search** — pass a public image URL and get the pages that host it (`sites[]`), visually `similar_images[]`, detected `tags[]` and the same image at `other_sizes[]`, via Yandex's two-step CBIR flow. ## Markets Yandex localises by **domain (TLD)**, not a query parameter. The `domain` parameter selects one of `tr` (yandex.com.tr), `com`, `ru`, `by`, `kz` or `uz`. The default is **`tr` (yandex.com.tr)** — measured to reliably clear Yandex's anti-bot. `com` and `ru` serve SmartCaptcha far more often and have a lower success rate; prefer `tr` unless you specifically need another region's index. [`GET /v1/yandex/markets`](/api-reference/endpoint/yandex/list-markets) (free) returns the supported domains with their default region (`lr`) and language. ## Credits | Endpoint | Path | Credits | | - | - | - | | Web search | `GET /v1/yandex/search` | 7 | | Image search | `GET /v1/yandex/images/search` | 7 | | Reverse image search | `GET /v1/yandex/images/reverse` | 7 | | List markets | `GET /v1/yandex/markets` | 0 | ## Quickstart ```bash cURL theme={null} curl "https://scrapebadger.com/v1/yandex/search?query=coffee+machine&domain=tr" \ -H "X-API-Key: YOUR_API_KEY" ``` ```javascript Node.js theme={null} const res = await fetch( "https://scrapebadger.com/v1/yandex/search?" + new URLSearchParams({ query: "coffee machine", domain: "tr" }), { headers: { "X-API-Key": process.env.SCRAPEBADGER_API_KEY } }, ); const data = await res.json(); console.log(data.result_count, "organic results"); ``` ```python Python theme={null} import requests res = requests.get( "https://scrapebadger.com/v1/yandex/search", headers={"X-API-Key": "YOUR_API_KEY"}, params={"query": "coffee machine", "domain": "tr"}, ) data = res.json() print(data["result_count"], "organic results") ``` ## Other notes * **The domain is the anti-bot lever.** `yandex.com.tr` clears reliably; `yandex.com`/`.ru` frequently serve SmartCaptcha. The scraper defaults to `tr` and recovers blocks by re-rolling a fresh Turkish residential exit. * **Organic `url` values are final destinations.** Yandex wraps results in a `/r?u=` tracking redirect; the API unwraps it so you get the real URL. * **Reverse image search is a two-step flow.** The API uploads/derives a `cbir_id` for your image, then reads the hosting pages, similar images, tags and other sizes. An image with no matches returns `is_empty: true`. ## Errors | Status | Meaning | | - | - | | `422` | Yandex served SmartCaptcha instead of content — **not billed**. Retry; a fresh exit usually clears it. | | `502` | Unexpected upstream failure — **not billed**. | Keep `domain=tr` for the highest success rate. Only switch domains when you specifically need another country's ranking, and expect a lower clear rate on `com`/`ru`. *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Yandex. "Yandex" is a trademark of Yandex LLC, used here only to describe the platform this scraper is designed to work with.* # YouTube Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/youtube/overview Scrape YouTube videos, Shorts, channels, playlists, comments, transcripts, trending, and community posts across regions with structured JSON responses. ## Scraper API for YouTube Search YouTube, pull full **video and Shorts detail**, fetch comments and replies, export **transcripts** (SRT/VTT/plain text), enumerate a channel's videos, shorts, streams, playlists, and community posts, and retrieve trending feeds, hashtags, and playlists — from the world's largest video platform. The API handles authentication, anti-bot bypass, and region routing automatically. ## Key Features 39 endpoints — videos, Shorts, channels, playlists, comments, transcripts, trending, hashtags, community posts, and music search. The [`/v1/youtube/videos/{id}/transcript`](/api-reference/endpoint/youtube/video-transcript) endpoint returns timed segments plus ready-to-use **SRT**, **VTT**, and full-text exports. Automatic session management, Chrome TLS impersonation, and fingerprint rotation to avoid blocks. Views, likes, chapters, heatmap (most-replayed), keywords, hashtags, live details, and streaming formats. Target any content region with `gl` and any UI language with `hl` for accurate, localized results. First-class support via the ScrapeBadger Node.js and Python SDKs. ## Regions & Languages YouTube results are localized by **content region** and **UI language**. Two query parameters control this on most endpoints: | Parameter | Meaning | Example | | - | - | - | | `gl` | Content region (ISO 3166-1 alpha-2 country code) | `US`, `GB`, `DE`, `JP` | | `hl` | UI / interface language (BCP-47 language code) | `en`, `de`, `fr`, `ja` | If omitted, `gl` defaults to `US` and `hl` defaults to `en`. Use the free [`/v1/youtube/regions`](/api-reference/endpoint/youtube/resolve-channel) and [`/v1/youtube/languages`](/api-reference/endpoint/youtube/resolve-channel) reference endpoints to fetch the full list of valid codes programmatically. ## Pagination YouTube list endpoints do **not** use page numbers. Every paginated response includes a `continuation` token; pass it back as the `continuation` query parameter to fetch the next page. When `continuation` is `null`, you have reached the end. ## Quick Start ```javascript Node.js theme={null} import ScrapeBadger from "scrapebadger"; const client = new ScrapeBadger({ apiKey: "YOUR_API_KEY" }); const results = await client.youtube.search({ query: "lofi hip hop", gl: "US", hl: "en", }); console.log(results.results); ``` ```python Python theme={null} from scrapebadger import ScrapeBadger client = ScrapeBadger(api_key="YOUR_API_KEY") results = client.youtube.search( query="lofi hip hop", gl="US", hl="en", ) print(results.results) ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/youtube/search?query=lofi+hip+hop&gl=US&hl=en" \ -H "x-api-key: YOUR_API_KEY" ``` ## Endpoints ### Search & Discovery | Endpoint | Method | Description | | - | - | - | | [`/v1/youtube/search`](/api-reference/endpoint/youtube/search) | GET | Search videos, channels, playlists, or movies | | [`/v1/youtube/autocomplete`](/api-reference/endpoint/youtube/search) | GET | Keyword autocomplete suggestions | | [`/v1/youtube/trending`](/api-reference/endpoint/youtube/trending) | GET | Trending feed (Now / Music / Gaming / Movies) | | [`/v1/youtube/trending/shorts`](/api-reference/endpoint/youtube/trending) | GET | Trending Shorts shelf | | [`/v1/youtube/hashtags/{tag}`](/api-reference/endpoint/youtube/hashtag) | GET | Videos under a hashtag | | [`/v1/youtube/home`](/api-reference/endpoint/youtube/trending) | GET | Guest home / recommendations feed | | [`/v1/youtube/music/search`](/api-reference/endpoint/youtube/music-search) | GET | YouTube Music search (songs, albums, artists) | ### Videos & Shorts | Endpoint | Method | Description | | - | - | - | | [`/v1/youtube/videos/{video_id}`](/api-reference/endpoint/youtube/get-video) | GET | Full video detail | | [`/v1/youtube/videos/batch`](/api-reference/endpoint/youtube/get-video) | POST | Up to 50 videos in one request | | [`/v1/youtube/videos/{video_id}/related`](/api-reference/endpoint/youtube/get-video) | GET | Related / recommended videos | | [`/v1/youtube/videos/{video_id}/comments`](/api-reference/endpoint/youtube/video-comments) | GET | Top-level comments | | [`/v1/youtube/videos/{video_id}/comments/{comment_id}/replies`](/api-reference/endpoint/youtube/video-comments) | GET | Replies to a comment | | [`/v1/youtube/videos/{video_id}/transcript`](/api-reference/endpoint/youtube/video-transcript) | GET | Timed transcript (SRT / VTT / text) | | [`/v1/youtube/videos/{video_id}/captions`](/api-reference/endpoint/youtube/video-transcript) | GET | Available caption tracks | | [`/v1/youtube/videos/{video_id}/streams`](/api-reference/endpoint/youtube/get-video) | GET | Streaming formats (best-effort URLs) | | [`/v1/youtube/videos/{video_id}/live_chat`](/api-reference/endpoint/youtube/get-video) | GET | Live chat / chat replay messages | | [`/v1/youtube/shorts/{video_id}`](/api-reference/endpoint/youtube/short) | GET | Full Shorts detail | | [`/v1/youtube/shorts/by_sound/{sound_id}`](/api-reference/endpoint/youtube/short) | GET | Shorts using a given sound | ### Channels | Endpoint | Method | Description | | - | - | - | | [`/v1/youtube/channels/{channel_id}`](/api-reference/endpoint/youtube/channel) | GET | Full channel detail (accepts `UC…`, `@handle`, or custom URL) | | [`/v1/youtube/channels/{channel_id}/videos`](/api-reference/endpoint/youtube/channel-videos) | GET | A channel's videos | | [`/v1/youtube/channels/{channel_id}/shorts`](/api-reference/endpoint/youtube/channel-videos) | GET | A channel's Shorts | | [`/v1/youtube/channels/{channel_id}/streams`](/api-reference/endpoint/youtube/channel-videos) | GET | A channel's live streams | | [`/v1/youtube/channels/{channel_id}/playlists`](/api-reference/endpoint/youtube/channel-videos) | GET | A channel's playlists | | [`/v1/youtube/channels/{channel_id}/community`](/api-reference/endpoint/youtube/channel-videos) | GET | A channel's community posts | | [`/v1/youtube/channels/{channel_id}/about`](/api-reference/endpoint/youtube/channel) | GET | Lightweight channel about payload | | [`/v1/youtube/channels/{channel_id}/subscriber_count`](/api-reference/endpoint/youtube/channel) | GET | Fast subscriber-count-only lookup | | [`/v1/youtube/channels/{channel_id}/search`](/api-reference/endpoint/youtube/channel-videos) | GET | Search within a channel | | [`/v1/youtube/channels/resolve`](/api-reference/endpoint/youtube/resolve-channel) | GET | Resolve a handle / URL to canonical ids | ### Playlists | Endpoint | Method | Description | | - | - | - | | [`/v1/youtube/playlists/{playlist_id}`](/api-reference/endpoint/youtube/playlist) | GET | Full playlist detail + first item page | | [`/v1/youtube/playlists/{playlist_id}/items`](/api-reference/endpoint/youtube/playlist-items) | GET | A page of playlist items | | [`/v1/youtube/mixes/{mix_id}`](/api-reference/endpoint/youtube/playlist) | GET | An auto-generated mix | ### Community & Reference | Endpoint | Method | Description | | - | - | - | | [`/v1/youtube/posts/{post_id}`](/api-reference/endpoint/youtube/community-post) | GET | A community post | | [`/v1/youtube/posts/{post_id}/comments`](/api-reference/endpoint/youtube/community-post) | GET | Comments on a community post | | [`/v1/youtube/oembed`](/api-reference/endpoint/youtube/resolve-channel) | GET | Public oEmbed metadata for a URL | | [`/v1/youtube/categories`](/api-reference/endpoint/youtube/resolve-channel) | GET | Video category reference list | | [`/v1/youtube/languages`](/api-reference/endpoint/youtube/resolve-channel) | GET | Supported UI languages (`hl`) | | [`/v1/youtube/regions`](/api-reference/endpoint/youtube/resolve-channel) | GET | Supported content regions (`gl`) | | [`/v1/youtube/markets`](/api-reference/endpoint/youtube/resolve-channel) | GET | Supported markets reference | ## Credit Costs | Endpoint | Cost | | - | - | | Search | 5 credits | | Trending / hashtag / home | 5 credits | | Music search | 5 credits | | Video detail | 10 credits | | Batch videos | 10 credits per video | | Related / comments / replies / live chat | 5 credits | | Transcript | 5 credits | | Streams | 15 credits | | Captions | 2 credits | | Short detail / shorts by sound | 5 credits | | Channel detail | 5 credits | | Channel videos / shorts / streams / playlists / community / search | 5 credits | | Channel about / subscriber count / resolve | 2 credits | | Playlist / playlist items / mix | 5 credits | | Community post / post comments | 5 credits | | Autocomplete / oEmbed | 1 credit | | Categories / languages / regions / markets | 0 credits | | Failed requests | 0 credits | ## Authentication All requests require your API key in the `X-API-Key` header: ```bash theme={null} curl "https://scrapebadger.com/v1/youtube/videos/dQw4w9WgXcQ" \ -H "X-API-Key: YOUR_API_KEY" ``` ## Anti-Bot Handling YouTube protects its data with IP-reputation scoring, TLS/HTTP-2 fingerprinting, bot-guard challenges, and PO-token requirements on media. ScrapeBadger clears these automatically using Chrome TLS impersonation on sessions matched to the target region. You never need to manage proxies, sessions, or tokens. For accurate, localized results, requests are routed through proxies in the `gl` region. This is handled automatically. Some fields (such as `dislike_count` and direct media `url`s) are restricted by YouTube platform-wide and may be `null`. ## Next Steps Full API reference for searching videos, channels, and playlists Fetch full metadata for a single video *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by YouTube. "YouTube" is a trademark of Google LLC, used here only to describe the platform this scraper is designed to work with.* # Zillow Scraper by ScrapeBadger — Overview Source: https://docs.scrapebadger.com/zillow/overview Scrape Zillow (zillow.com) real-estate listings — search, maximal property detail with resoFacts, price/tax/Zestimate history, schools, and agent profiles — with structured JSON responses. ## Scraper API for Zillow Search for-sale, for-rent, and sold listings, pull **maximal property detail** with the full `resoFacts` home-facts block, price / tax / Zestimate history, schools, and listing-agent attribution, look up agent profiles with reviews and past sales, and autocomplete locations across **zillow\.com** — a dedicated Zillow real-estate API. The API handles authentication, anti-bot bypass, and session/proxy routing automatically. ## Key Features Zillow's for-rent inventory is mostly apartment communities (`home_type: "BUILDING"`), which have no single price or zpid. The [`/v1/zillow/building`](/api-reference/endpoint/zillow/get-building) endpoint returns their floor plans and **every available unit** with rent, sqft, and move-in date, plus amenities, office hours, pet policy, schools, and walk/transit/bike scores. \~99 top-level fields per property plus a nested `home_facts` block distilled from Zillow's `resoFacts` MLS record — beds, baths, sqft, lot size, systems, features, HOA, parcel, and more. Full **price history**, **tax history**, and **Zestimate value history** on the [`/v1/zillow/property/{zpid}`](/api-reference/endpoint/zillow/get-property) detail endpoint, plus current Zestimate and Rent Zestimate. Nearby schools with ratings, listing-agent attribution, and full [agent profiles](/api-reference/endpoint/zillow/get-agent) with reviews, past sales, and licenses. Beat Zillow's \~820-result (20-page) cap by re-issuing a search over subdivided `north`/`south`/`east`/`west` map-bound boxes returned in `map_bounds`. Automatic session management, Chrome TLS impersonation, and fingerprint rotation to avoid blocks. Requests are pinned to US residential IPs — Zillow serves all inventory (including Canadian MLS feeds) from zillow\.com behind a US IP. Zillow caps a single search at **20 pages (\~820 results)**. For dense metros, split the area into smaller `north`/`south`/`east`/`west` map-bound tiles using the `map_bounds` box returned on each search. ## Coverage Zillow is a **single-domain, single-locale** target: every market is served from `zillow.com` in USD / en-US behind a US residential IP. `zillow.ca` redirects to zillow\.com and Canadian inventory is an MLS data feed surfaced inside zillow\.com — there is no separate Canadian portal or currency/locale switcher. | Market | Portal | Country | Currency | Locale | | - | - | - | - | - | | :us: `US` | zillow\.com | US | USD | en-US | | :canada: `CA` | zillow\.com | CA | USD | en-US | Use the [`/v1/zillow/markets`](/api-reference/endpoint/zillow/list-markets) endpoint to get the advertised coverage (with domain, currency, and locale) programmatically. Markets are informational only — there is no `market` routing parameter. ## Quick Start ```javascript Node.js theme={null} import ScrapeBadger from "scrapebadger"; const client = new ScrapeBadger({ apiKey: "YOUR_API_KEY" }); const results = await client.zillow.search({ location: "Austin, TX", status: "for_sale", }); console.log(results.results); ``` ```python Python theme={null} from scrapebadger import ScrapeBadger client = ScrapeBadger(api_key="YOUR_API_KEY") results = client.zillow.search( location="Austin, TX", status="for_sale", ) print(results.results) ``` ```bash cURL theme={null} curl "https://scrapebadger.com/v1/zillow/search?location=Austin,+TX&status=for_sale" \ -H "x-api-key: YOUR_API_KEY" ``` ## Endpoints | Endpoint | Method | Description | | - | - | - | | [`/v1/zillow/search`](/api-reference/endpoint/zillow/search) | GET | Search Zillow for listings | | [`/v1/zillow/property/{zpid}`](/api-reference/endpoint/zillow/get-property) | GET | Full detail for a single property | | [`/v1/zillow/building`](/api-reference/endpoint/zillow/get-building) | GET | Multifamily building — floor plans and per-unit rents | | [`/v1/zillow/agent`](/api-reference/endpoint/zillow/get-agent) | GET | Agent profile, reviews, past sales, listings | | [`/v1/zillow/autocomplete`](/api-reference/endpoint/zillow/autocomplete) | GET | Location autocomplete suggestions | | [`/v1/zillow/markets`](/api-reference/endpoint/zillow/list-markets) | GET | List advertised coverage markets | ## Credit Costs | Endpoint | Cost | | - | - | | Search | 5 credits | | Get property detail | 5 credits | | Get multifamily building | 5 credits | | Get agent profile | 5 credits | | Autocomplete | 2 credits | | List markets | 0 credits | | Failed requests | 0 credits | ## Authentication All requests require your API key in the `X-API-Key` header: ```bash theme={null} curl "https://scrapebadger.com/v1/zillow/search?location=Miami,+FL" \ -H "X-API-Key: YOUR_API_KEY" ``` ## Anti-Bot Handling Zillow protects its listings with PerimeterX/HUMAN fingerprinting, IP-reputation scoring, and TLS/HTTP-2 fingerprinting, and renders most data as embedded page JSON (`__NEXT_DATA__` search state and `gdpClientCache` property detail). ScrapeBadger clears these automatically using Chrome TLS impersonation on US-pinned sessions. You never need to manage proxies, sessions, or CAPTCHAs. A few Zillow datapoints (comparable sales, Walk/Transit/Bike scores, climate risk) are lazy-loaded client-side and are **not** in the server-rendered JSON, so they are intentionally absent from responses. ## Rich Datapoints Every property carries a deep set of structured fields: | Group | Fields | | - | - | | **Pricing** | `price`, `zestimate`, `rent_zestimate`, `tax_assessed_value`, `monthly_hoa_fee`, `property_tax_rate`, `last_sold_price`, `price_change` | | **Size** | `bedrooms`, `bathrooms`, `living_area`, `lot_size`, `lot_area_value`, `year_built`, plus `home_facts` bath/story/area breakdowns | | **Location** | `street_address`, `city`, `state`, `zipcode`, `county`, `neighborhood`, `latitude`, `longitude`, `time_zone` | | **Media** | `photos[]`, `photo_count`, `virtual_tour_url`, `has_3d_model`, `street_view_image_url`, `static_map_url` | | **History** | `price_history[]`, `tax_history[]`, `zestimate_history[]`, `days_on_zillow` | | **Facts** | `home_facts` (heating, cooling, appliances, flooring, parking, pool, HOA, green, features, parcel — \~125 fields) | | **Context** | `schools[]`, `home_insights[]`, `open_house_schedule[]`, `nearby_cities/neighborhoods/zipcodes`, `agent` attribution, `mortgage_rates` | Search returns each result as a `Listing` (\~50 fields); the [property detail](/api-reference/endpoint/zillow/get-property) endpoint returns a full `Property` with the nested `home_facts`, history, schools, and agent blocks. ## Next Steps Full API reference for searching the Zillow catalog Retrieve full detail, home facts, price/tax/Zestimate history, schools, and agent for a property Apartment communities — floor plans, per-unit rents, availability, amenities, and schools *** *ScrapeBadger is an independent tool and is not affiliated with, endorsed by, or sponsored by Zillow. "Zillow" is a trademark of Zillow, Inc., used here only to describe the platform this scraper is designed to work with.*