",
"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 `
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.*