Tokopedia Scraper - Products, Prices, Sellers & Variants
Pricing
from $1.00 / 1,000 product scrapeds
Tokopedia Scraper - Products, Prices, Sellers & Variants
Extract product data from Tokopedia, Indonesia’s largest marketplace. Search by keyword with sorting and filters, or use product/result URLs. Returns price, discount, rating, sold count, seller, category, images, and optional details like description, videos, variants, and wholesale tiers.
Pricing
from $1.00 / 1,000 product scrapeds
Rating
4.0
(1)
Developer
Abot API
Maintained by CommunityActor stats
2
Bookmarked
47
Total users
10
Monthly active users
4 days ago
Last modified
Categories
Share
Tokopedia Scraper: Products, Prices, Variants, Sellers
Tokopedia Scraper turns Tokopedia into structured product data. Search by keyword with price, rating, condition, seller-tier and discount filters, or paste product and search-result URLs directly. Every record carries the price, discount, rating, seller and category, and with detail fetching on, the sold and review counts, the full description, every image and video, variants, wholesale tiers and live stock. Export to JSON, CSV or Excel, or pull results straight into your app through the API.
Why This Scraper?
- Two ways in. Search by keyword with filters and sorting, or paste product and search-result URLs directly. No need to build query strings by hand.
- Filters apply to both modes. Price, rating and discount narrow even a single pasted product URL, not just a keyword search.
- Full detail on demand. Turn on detail fetching to add the complete description, every image and video, variants, wholesale price tiers, live stock and seller flags, and pay only for the products you enrich.
- Seller and pricing depth. Seller tier, city and badges, plus original price, discount percentage and active flash-sale campaign data when a product is genuinely running one.
- Built for monitoring. Resume an interrupted crawl without re-collecting or re-paying for products already gathered, or track the same search on a schedule and get back only new and changed products.
- Indonesia-scale catalogue. Search Tokopedia's marketplace across any category, from electronics and fashion to groceries and home goods.
- Clear failures. A run that cannot read a resume dataset stops with a clear error instead of silently returning nothing.
Use Cases
- Price and stock monitoring: track competitor prices, discounts and stock levels on a recurring schedule.
- Catalogue research: analyze category breadth, seller tiers and badges across a keyword or category.
- Product data feeds: enrich your own storefront, comparison site or price-tracking app with structured Tokopedia listings.
- Flash-sale and deal tracking: capture active campaign pricing, stock and timing on the products you follow.
- Seller intelligence: compare official stores and power merchants by rating, review count and sold count.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
productId | "11690069936" |
name | "Sepatu Sneakers Pria Casual" |
url | Tokopedia link to the product |
categoryName / categoryBreadcrumb | "Sepatu Pria" / "Pria/Sepatu Pria/Sneakers" |
price / priceText | 150000 / "Rp150.000" |
originalPrice / discountPercentage | 200000 / 25 |
isOnSpecial / specialsCategory | true / "Flash Sale" (isOnSpecial is true for any active discount; specialsCategory is filled only on fetched product details when a campaign is active) |
rating / reviewCount | 4.8 / 1240 (review count: fetched product details only) |
soldCount / soldText | 500 / "500+ terjual" (read from the listing label when the site shows one, a rounded lower bound such as 10 rb+ = 10000; the exact count comes with fetched product details) |
condition | "Baru" (fetched product details only) |
stock / stockText | 85 / "Tersedia" (fetched product details only) |
shopName / shopCity | "Toko Sepatu Jaya" / "Jakarta Barat" |
shopTier | 3 (numeric seller tier code from the site; not the same as the shopTier input filter, which takes official_store or power_merchant) |
isOfficialStore / isPowerMerchant | false / true (fetched product details only) |
image | product image URL |
gallery / videos | every product photo and video (fetched product details only) |
reviews | newest customer reviews as a nested array: reviewer, rating, date, text, seller reply, helpful votes (fetched product details only; count set by maxReviews) |
variants | size and colour options with names and swatches (fetched product details only) |
wholesale | quantity price tiers (fetched product details only) |
description | full product description text (fetched product details only) |
changeType | "NEW", "UPDATED", "UNCHANGED", "REAPPEARED", or "EXPIRED" (incremental mode only) |
How to Use
- Pick a mode:
search(build from keywords and filters) orurl(paste product or search-result links). - In Search mode, enter your keywords and set any filters. In URL mode, paste the links; filters still narrow what a pasted search-result URL returns, and price, rating and discount also narrow a single pasted product URL.
- Turn on Fetch full product details if you need the description, all media, variants and stock. Set Max items to control run size and cost.
- Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API.
Search with filters:
{"mode": "search","searchTerms": ["sepatu"],"sortBy": "price_asc","minPrice": 100000,"condition": "new","maxItems": 50}
Paste a search-result URL:
{"mode": "url","urls": ["https://www.tokopedia.com/search?q=sepatu"],"maxItems": 100}
Official-store search with full product details:
{"mode": "search","searchTerms": ["iphone"],"shopTier": "official_store","fetchDetails": true,"maxItems": 20}
Recurring search that returns only changes:
{"mode": "search","searchTerms": ["laptop"],"incrementalMode": true,"stateKey": "laptop-watch"}
Supported URL shapes
| Link | Result |
|---|---|
/search?q=... (also page, ob, pmin, pmax, condition, rt, shop_tier) | listed products, link filters applied |
/p/<category>/<sub> and /find/<slug> | search on the slug words |
/<shop>/<product> (tracking query like extParam ignored) | full product record |
m.tokopedia.com/... | treated like www |
/<shop>, /<shop>/product, /<shop>/product/page/<n> | the shop's product list, 80 products per page (price, rating and discount filters apply; sort, condition, seller type and free shipping do not) |
/<shop>/review | the shop's newest customer reviews, one row per reviewed product with up to Reviews per product reviews nested under reviews (10 reviews per page, Max pages per search bounds the pages, Max items bounds the products) |
other shop tabs (/etalase, /info, ...), tokopedia.link/... | not supported, a warning is logged per URL |
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/tokopedia-scraper").call(run_input={"mode": "search", "searchTerms": ["sepatu"]})for product in client.dataset(run["defaultDatasetId"]).iterate_items():print(product["name"], product["priceText"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/tokopedia-scraper').call({ mode: 'search', searchTerms: ['sepatu'] });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Max items and Max pages
Max items is the single cap on how many products a run returns; set it to 0 for no limit. Max pages per search is only a safety bound on result pages walked per keyword; it does not cap the number of products. Leaving it empty or 0 means up to 100 pages per keyword (a hard cap), and any value above 100 is treated as 100, so a very large Max items can still return fewer products than asked for on a keyword that has more than 100 pages.
Resume and recurring updates
- Resume (
resumeFromRunId) continues one specific interrupted run: paste its run or dataset ID and this run skips every product already collected there, so you don't pay twice for the same crawl. - Incremental mode (
incrementalMode) is for scheduling the same search or URL list again and again, for example daily. The actor remembers the previous run of that exact search by itself, so no run ID is needed. The first run returns everything asNEW. Later runs classify each product asNEW,UPDATED(withchangedFieldslisting what changed),UNCHANGED(suppressed and not billed unless Emit unchanged is on),REAPPEARED, orEXPIRED(only after a run that fully scanned the tracked search, and only with Emit expired on). A product isUPDATEDwhen any returned field changes (price, discount, stock, rating, sold count, title, images, description and so on). Never compared:scrapedAt, signed image and video link hosts and tokens (only the image path counts), and tracking tokens inside URLs. Ignore fields when detecting changes (ignoreFieldsForChanges) adds your own field names to that list, wherever they appear, while still returning them.stateKeynames or shares a monitoring campaign; leave it empty and the actor derives one from the search terms or URLs, the active filters, and the detail setting. Shop product lists (/<shop>,/<shop>/product) carry fewer fields than search results, so for those rows the category, image, rating, labels, shop tier, listing position and search context are left out of the comparison (they are still returned), and a product first stored from a search is not markedUPDATEDjust because a shop page showed it. Starting a link at a later page (/product/page/2,?page=3) never triggersEXPIRED. Shop review rows (/<shop>/review) are tracked per product by their review IDs: a row isNEWthe first time,UPDATEDwhen the set of reviews returned for that product changes, and neverEXPIRED. With incremental mode off, output is exactly as before.
Send results into your apps (MCP connectors)
Optionally push each scraped product into apps you already use, through Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape; the Apify dataset is never changed.
What gets sent: a condensed, human-readable summary of each product, a title plus its key fields flattened to plain text, not the full JSON record. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify, Settings, Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the Export to your apps (MCP) input field. If the picker is empty, you haven't authorized a connector yet.
- For Notion, also set
notionParentPageUrlto the page under which product pages should be created. - Optionally set Max items to export to cap how many products are pushed to each connector per run (defaults to 50 when left empty).
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | search | search (keyword + filters) or url (paste product or result URLs). |
searchTerms | array | [] | Keywords to search for, e.g. "sepatu", "laptop", "iphone". Search mode only. |
urls | array | 10 example links (one per supported shape) | URL mode only. Supported: search (with page, ob, pmin, pmax, condition, rt, shop_tier read from the link), /p/<category>/<sub> and /find/<slug> (the slug is used as the keyword), product pages (tracking query stripped), m.tokopedia.com links, shop pages (/<shop> or /<shop>/product, with /product/page/<n> to start at a later page: 80 products per page, then the same filters as above) and shop review pages (/<shop>/review: one row per reviewed product with its newest reviews nested). Other shop tabs and tokopedia.link short links are not supported and log a warning per URL. Filters you set in the input win over the link's own. Behaviour change: the field now ships with these examples as its default instead of an empty list. |
sortBy | string | relevance | Result ordering: relevance, newest, most_reviewed, price_asc, or price_desc. Applies in Search mode and to a pasted search URL; not to a pasted product URL or shop URL. |
minPrice | integer | (none) | Keep only products at or above this price, in Indonesian Rupiah. Applies in Search mode and to a pasted product, shop or search URL. |
maxPrice | integer | (none) | Keep only products at or below this price, in Indonesian Rupiah. Applies in Search mode and to a pasted product, shop or search URL. |
condition | string | any | any, new, or used. Applies in Search mode and to a pasted search URL; not to a pasted product URL or shop URL. |
minRating | integer | (none) | Keep only products with an average rating at or above this value (1 to 5). Applies in Search mode and to a pasted product, shop or search URL. |
shopTier | string | any | any, official_store, or power_merchant. Applies in Search mode and to a pasted search URL; not to a pasted product URL or shop URL. |
freeShippingOnly | boolean | false | Keep only products eligible for free shipping. Applies in Search mode and to a pasted search URL; not to a pasted product URL or shop URL. |
discountOnly | boolean | false | Keep only products with an active discount. Applies in Search mode and to a pasted product, shop or search URL. |
fetchDetails | boolean | false | Adds the full description, every image and video, variants, wholesale tiers, stock, sold and review counts, weight, condition and seller flags. |
maxReviews | integer | 20 | With detail fetching on, newest reviews attached to each product; a shop /review link returns reviews with or without detail fetching (0 = none, capped at 1000 per product). Reviews are ignored when deciding whether a product changed in incremental mode. |
maxPages | integer | (none) | Safety bound on pages walked per keyword (or per shop reviews link). Empty or 0 means the hard cap of 100 pages; values above 100 are clamped to 100. This does not cap the number of products. |
maxItems | integer | 20 | Maximum number of products to return across the whole run. 0 is unlimited. |
resumeFromRunId | string | (none) | Paste a previous run ID or dataset ID to continue a large crawl without returning or charging for products already collected there. |
incrementalMode | boolean | false | Turn on for daily or recurring monitoring; returns only new and changed products against remembered state. |
stateKey | string | (none) | Optional name for an incremental-mode monitoring campaign. Leave empty to derive one automatically from the search or URLs, the active filters, and the detail setting. |
emitUnchanged | boolean | false | Incremental mode only. Also return (and bill for) products with no change since the last run. |
emitExpired | boolean | false | Incremental mode only. Also return (and bill for) products no longer found, once a run has fully scanned the tracked search. |
ignoreFieldsForChanges | array | [] | Incremental mode only. Field names left out of UPDATED detection and changedFields, at any nesting level (for example soldCount); the fields are still returned in the output. |
proxy | object | {"useApifyProxy": true} | Connection settings. Keep Apify Proxy enabled for the most complete results. |
mcpConnectors | array | [] | Optional: send a summary of each product to apps you authorized under Integrations. |
notionParentPageUrl | string | (none) | Notion connector only: page under which product pages are created. |
maxNotifyListings | integer | (none) | Alias of maxNotifyItems; either may be used. |
maxNotifyItems | integer | (none) | Optional cap on how many products are pushed to the selected MCP connectors (defaults to 50 when left empty). |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
{"productId": "11690069936","productKey": "sepatu-sneakers-pria-casual","name": "Sepatu Sneakers Pria Casual","url": "https://www.tokopedia.com/tokosepatujaya/sepatu-sneakers-pria-casual","categoryName": "Sepatu Pria","categoryBreadcrumb": "Pria/Sepatu Pria/Sneakers","price": 150000,"priceText": "Rp150.000","originalPrice": 200000,"discountPercentage": 25,"isOnSpecial": true,"specialsCategory": "Flash Sale","rating": 4.8,"reviewCount": 1240,"soldCount": 500,"soldText": "500+ terjual","condition": "Baru","stock": 85,"stockText": "Tersedia","minOrder": 1,"weight": 800,"weightUnit": "gr","image": "https://images.tokopedia.net/img/product/sample.jpg","gallery": [{ "type": "image", "original": "https://images.tokopedia.net/img/product/sample-1.jpg" }],"videos": [],"variants": [{ "type": "Ukuran", "options": [{ "name": "40" }, { "name": "41" }, { "name": "42" }] }],"wholesale": [{ "minQty": 3, "price": 140000 }],"description": "Sepatu sneakers pria bahan kanvas, nyaman dipakai harian, tersedia berbagai ukuran.","shopId": "2000001","shopName": "Toko Sepatu Jaya","shopCity": "Jakarta Barat","shopTier": 3,"isOfficialStore": false,"isPowerMerchant": true,"badgeTitle": "Power Merchant","searchQuery": "sepatu","searchPage": 1,"searchPosition": 3,"platform": "tokopedia","mode": "detail","scrapedAt": "2026-09-28T04:00:00.000Z"}
Output views. The run's Output tab has five views over the same data: Products (the search and listing fields), Product details (description, media, variants, wholesale tiers, stock; filled when Fetch full product details is on), Reviews (one row per review, unwound from each product's reviews array), Changes (incremental) (changeType and changedFields; incremental mode only), and a Run summary with the run's counts and status message.
Plan Requirement
The default connection ({"useApifyProxy": true}) works on a plan that includes Apify Proxy: the actor tries Apify datacenter proxy first. Only if a connection fails does it move on to Apify residential proxy, and then to a backup connection. If you supply your own proxy URLs, they are used as given.
Apify free plans do not include Apify Proxy access, so a free-plan run goes straight to the backup connection. The run logs this notice, and says so again once pages are served that way:
The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable. For residential access, upgrade at https://apify.com/pricing or supply your own proxy URLs.
On the backup connection some pages may still be unavailable. If it cannot load the pages either, the run finishes with zero products and this message:
No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested Tokopedia pages. Upgrade at https://apify.com/pricing or supply your own proxy URLs, then try again.
If the proxy is refused outright, the message is:
The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required: https://apify.com/pricing. If you entered your own proxy URLs, check that their credentials are valid.
If every results page request fails, the message is:
Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search. Please try again later.
There is no direct-connection fallback.
FAQ
How much does it cost?
You pay a small charge when a run starts, a charge per product returned, and an extra charge only for products where Fetch full product details was on. The Pricing tab shows the current rates. Reviews add no extra charge: nested reviews ride on the per-product row, and the detail charge applies once per product whose full detail is fetched (shop /review rows are not detail-fetched, so they add no detail charge). Use Max items and Reviews per product to cap the cost of any run.
Is it legal to scrape Tokopedia?
This actor collects only publicly available product listings from Tokopedia. You are responsible for how you use the data: follow Tokopedia's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Product names and prices are generally facts, but photos, videos and descriptions may be subject to third-party rights.
Can I get only new or changed products on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. The first run returns everything as NEW; later runs return only NEW, UPDATED and REAPPEARED products by default, and unchanged ones are not billed.
What's the difference between Resume and Incremental mode?
Resume (resumeFromRunId) continues ONE specific interrupted run using a pasted run or dataset ID. Incremental mode is for running the SAME search or URL list again and again on a schedule; the actor remembers state on its own, so no ID is pasted. Combining both only works to bootstrap a new incremental campaign from an existing dataset; if incremental state already exists for that search, the run stops with an error asking you to remove Resume or choose a different State key.
Why did my run fail instead of returning an empty dataset?
A run fails, rather than finishing with zero products, only when Resume from a previous run points at an ID this account cannot read, or when it's combined with Incremental mode that already has saved state for the same search. Everything else, including the site refusing requests or a search matching nothing, finishes as a successful run with zero products and a status message explaining why. Check the run's status message and log before assuming something is broken.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the Export to your apps field to push scraped products into Notion, Linear or Airtable.
🔗 Want more e-commerce data?
Pair this actor with these related scrapers from the same team:
| 🛒 Trendyol Scraper From $0.80/1K. Scrape Trendyol products, prices, ratings, badges, sellers, full reviews... | 🛒 Thegioididong Scraper Scrape thegioididong.com products with full specifications, current & original price... |
| 🛒 Nitori Japan Furniture & Home Goods Scraper Scrape Nitori Japan (nitori-net.jp) furniture and home goods by keyword, category or... | 🛒 Cdiscount Scraper Scrape product data from Cdiscount.com by keyword, category, or URL. Apply filters and... |
| 🛒 Lazada Scraper Scrape Lazada products and reviews across SEA markets, including Malaysia, Singapore... | 🛒 Ozon.ru Scraper Extract structured product data from Ozon.ru, Russia’s largest marketplace. Search by... |
💬 Support
- 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com.
- ⭐ Enjoying it? A quick review on the actor page helps other users find it.