
TikTok Shop Scraper
scrape.ly/store/shelfbright/tiktok-shop-scraperE-commerceSocial media
1 monthly user

Scrape public Shopify products, variants, prices, images, and collections from a store, a collection, a product page, or a keyword search.
Scrape public products, variants, prices, stock status, images and collections from any Shopify store. Point it at a store home page, a collection, a single product, the collections index, or search a store by keyword, and get one structured row per product.
Products cost $0.50 per 1,000, and the optional extras are separate, opt-in events.
/collections index.minPrice and maxPrice./collections URL.| Field | Type | Description |
|---|---|---|
startUrls | array (required) | Store home page, collection URL, product URL or collections index. |
query | string | Search each store instead of crawling the URL path. |
maxResults | integer | Records to save. Default 10. 0 means no cap, so set a run charge limit first. |
minPrice, maxPrice | number | Price window in store currency (140 means 140.00), applied to the lowest variant. |
maxRecommendationsPerProduct | integer | Nest related products. Each is a separate charge. |
grabRealInventory | boolean | Add a stock count when the store publishes one. |
grabStorefrontDetail | boolean | Selling plans and videos on collection and catalog crawls. |
grabContentSections | boolean | Information panels from the product page, when present. |
proxyConfiguration | object | Datacenter by default. |
{
"startUrls": [{ "url": "https://kith.com/collections/kith-tops" }],
"maxResults": 10
}
To read prices in another currency add ?currency=EUR to the start URL, or use a locale path such as /en-gb/.
One dataset row per product. A /collections URL returns one row per collection instead. Prices are integers in minor units: 199500 means 1995.00 in source.currency.
| Field | Description |
|---|---|
source | Store id, canonical URL, retailer, language, currency and timestamps. |
title, brand, categories, tags | Product identity. |
price | current, previous and stockStatus (InStock, OutOfStock, LowInStock). |
priceRange | min, max and whether prices vary. |
options, variants, medias | Option names, per-variant data and images. |
fullyOutOfStock | True when every variant is out of stock. |
Example product (trimmed):
{
"source": {
"id": "8286829772928",
"canonicalUrl": "https://kith.com/products/gm005893u7304",
"retailer": "Kith",
"language": "en",
"currency": "USD"
},
"title": "Giorgio Armani & Kith Ivy Wool Crepe Shirt - Stadium",
"brand": "Kith",
"categories": ["Button Up Shirts"],
"price": { "current": 199500, "previous": 0, "stockStatus": "InStock" },
"priceRange": { "min": 199500, "max": 199500, "varies": false },
"fullyOutOfStock": false
}
LowInStock appears only when a real count was read and it is from 1 to 5. A collection row looks like this:
{
"id": "421591943",
"title": "Summer",
"handle": "summer",
"productsCount": 12
}
| Event | Price | When it is charged |
|---|---|---|
| Product | $0.0005 | Once per product saved ($0.50 per 1,000) |
| Collection | $0.0003 | Once per collection saved from a /collections URL |
| Recommended product | $0.0003 | Once per related product nested on a product |
| Real inventory | $0.0003 | Once per product that includes a published stock count |
| Information panels | $0.0001 | Once per product with at least one panel |
Worked example: 10 products from one collection cost $0.005 in product fees, and about $0.007 in total with compute and storage in our test. A product reached twice in the same run is saved once. Extras are off by default, and a store that does not publish stock counts is not charged for inventory. When a product's extras would go over your maximum charge, the product keeps only the extras the remaining budget pays for (real inventory first, then information panels, then recommended products), is charged for exactly those, and is marked truncatedAtChargeLimit: true; the run then stops.
Is it legal to scrape a Shopify store? The actor reads only publicly available product data. You are responsible for using it in line with applicable law and each store's terms.
Do I need a login or my own proxy? No. Datacenter proxies are included; pick residential only if a store refuses datacenter addresses.
What happens on a site that is not Shopify? The run succeeds and saves nothing for that site. The status line says it is not a Shopify store.
Why is the price a large integer?
It is in minor units. For US dollars, divide by 100. source.currency names the currency.
Why is there no stock count? Turn on Real inventory counts. Stores that do not publish a number still return in stock or out of stock, and are not charged for a count.
Can I schedule it or use the API? Yes, via schedules or the API.
updatedUTC and other timestamps follow whatever the store publishes.Every field below can be set in the run form, passed through the API, or saved as a task. Unset fields fall back to the defaults shown.
startUrlsarrayRequiredStore URLs
A store home page crawls the catalog. A collection URL crawls that collection. A product URL saves that product. The collections index (a URL ending in /collections) saves collection records instead of products.
querystringOptionalSearch query
When set, each store is searched for this text instead of crawling the URL path. A store with no public search results is skipped.
maxResultsintegerOptionaldefault 10Maximum records
Stop after this many products or collections are saved. 0 means no limit, so use the run charge cap to bound a full catalog.
Optional price window in the store's currency. Collection records are not filtered.
minPricenumberOptionalMinimum price
Keep products whose lowest variant is at least this amount, in the store currency (140 means 140.00). Leave empty to skip.
maxPricenumberOptionalMaximum price
Keep products whose lowest variant is at most this amount, in the store currency. Leave empty to skip.
Off by default. Each option adds requests and, where noted, an extra charge.
maxRecommendationsPerProductintegerOptionaldefault 0Maximum recommended products
Related products nested on each product. 0 turns this off. Each recommended product is a separate charge. Shopify's recommendation feed returns at most 10 per product.
grabRealInventorybooleanOptionaldefault falseReal inventory counts
Add per-variant stock counts when the store publishes them. Stores that do not publish a count are not charged for this.
grabStorefrontDetailbooleanOptionaldefault falseSelling plans and videos
On collection and catalog crawls, also read subscription plans and product videos. Product URLs always include this.
grabContentSectionsbooleanOptionaldefault falseInformation panels
Add labelled panels from the product page, such as materials or care, when the page shows them. Products without panels are not charged.
maxRequestsPerCrawlintegerOptionalMaximum records (alias)
Alias of Maximum records. Used only when Maximum records is omitted.
maxInventoryFetchesintegerOptionaldefault 0Inventory fetch cap
Cap extra per-product inventory fetches on collection crawls. 0 means no cap.
maxStorefrontFetchesintegerOptionaldefault 0Storefront fetch cap
Cap extra selling-plan fetches on collection crawls. 0 means no cap. Product URLs are not capped by this.
maxContentSectionFetchesintegerOptionaldefault 0Panel fetch cap
Cap product-page panel fetches. 0 means no cap. A single product URL is not capped by this.
proxyConfigurationobjectOptionaldefault {"useScrapelyProxy":true,"scrapelyProxyGroups":["DATACENTER…Proxy configuration
Datacenter proxies are the default. Pick residential only when a store refuses datacenter addresses, or turn the proxy off and supply your own URLs.
Every run writes its results to a dataset. Preview it in the dashboard, then export it or read it through the API.
| Field | Type | Description |
|---|---|---|
| source | object | Ids, public URL, currency, and timestamps for a product. |
| title | string | Product or collection title |
| description | string | HTML description |
| brand | string | Vendor name |
| categories | array | |
| tags | array | |
| price | object | Lowest variant price in minor units. |
| priceRange | object | |
| fullyOutOfStock | boolean | |
| handle | string | Collection handle |
| productsCount | integer | Products in a collection |
| id | string | Collection id |
| canonicalUrl | string | |
| truncatedAtChargeLimit | boolean | Present (true) when the product's extras were cut to what the run's maximum charge still paid for. |
You pay for the events the actor reports, such as each result or page it produces. Platform usage is included in the event prices.
| Event | Charged when | Price |
|---|---|---|
| Collection | Charged once per collection saved from a collections index URL. | $0.0003 |
| Information panels | Charged once per product that includes information panels. | $0.0001 |
| Product | Charged once per product saved, including its variants, prices, stock status, images, options, and tags. | $0.0005 |
| Real inventory | Charged once per product that includes a published stock count. | $0.0003 |
| Recommended product | Charged once per related product nested on a saved product. | $0.0003 |
Run this actor from your own code. Swap in your API token and the examples work as-is.
import { ScrapelyClient } from 'scrapely-client'
const client = new ScrapelyClient({ token: process.env.SCRAPELY_TOKEN })
// Start the actor and wait for the run to finish.
const run = await client.actor('shelfbright/shopify-scraper').call({
"startUrls": [
{
"url": "https://kith.com/collections/kith-tops"
}
],
"query": "",
"maxResults": 10,
"maxRecommendationsPerProduct": 0,
"grabRealInventory": false,
"grabStorefrontDetail": false,
"grabContentSections": false,
"proxyConfiguration": {
"useScrapelyProxy": true,
"scrapelyProxyGroups": [
"DATACENTER"
]
}
})
// Read the dataset the run produced.
const { items } = await client.dataset(run.defaultDatasetId).listItems()
console.log(items)Tokens live in your account settings. Keep them server-side: a token carries the full permissions of your account.
Connect the Scrape.ly MCP server once and your agent can run this actor as a tool. Pick your tool:
Fetch scrape.ly/agents.md and run shelfbright/shopify-scraperPaste into Claude Code, Codex, Cursor or any AI agent. It signs you in once in the browser.
{
"mcpServers": {
"scrapely": {
"url": "https://api.scrape.ly/mcp?tools=actors,runs,storage,docs&actors=shelfbright/shopify-scraper"
}
}
}No key in the file: your client opens the browser to sign you in the first time it connects.
Inputs the developer prepared for common jobs. Open one to see its input, then copy it to your account to run it as-is or adjust it.
Products from a store collection within a price range.
Products with real inventory levels per variant.
Products with storefront details and related products.
Scrape.ly gives you the infrastructure, the tooling, and the team to extract, process, and operationalize web data at any scale. Setup takes minutes. The advantage lasts forever.