Shopee API & Scraper
The Shopee API returns products, per-variant stock, seller profiles and shop vouchers from seven Southeast-Asian Shopee markets — Indonesia, Vietnam, Thailand, the Philippines, Malaysia, Singapore and Taiwan — as clean JSON.
🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.
The primary product endpoint returns an item's title, plain-text and block-structured description, brand, condition, currency, item_status, created_at, images, videos, the category path, per-variant stock and the shop's vouchers; Shopee withholds the price on that surface, so the response reports price_available and names the fields it could not carry rather than inventing them. shop_showcase is the surface that does carry pricing — price, price_before_discount, discount_percent, the rating breakdown, review_count and sold counts. batch resolves a list of items in one call and bills delivered products only, and shop returns a seller profile with item_count, follower_count, ratings, response rate and the official and verified flags. One ReefAPI key, one shared credit pool, the standard envelope.
Shopee's two-part key, the seven markets, and the 100000 price scale
A Shopee product is not addressable by one id. It takes the shop and the item together, in that order, and the same item_id on another market is a different product or nothing at all. Prices are the other surprise: Shopee stores them scaled by 100000, and both the raw integer and the divided figure are returned so you can check the arithmetic. Measured on 2026-08-27 on shopee.co.id.
| Field | Format | Measured |
|---|---|---|
| shop_id | integer, the FIRST number in /product/<shop_id>/<item_id> | 165796339 (9 digits) and 27651338 (8) - no fixed length |
| item_id | integer, the SECOND number in that path | 4669874676 (10 digits) and 26270321805 (11) |
| market | a closed set of seven | id, vn, th, ph, my, sg, tw. Sending 'br' returns INVALID_PARAM with that list in the error detail |
| currency_scale | the divisor Shopee's raw numbers use | 100000, on both the product and shop_showcase actions |
| price_raw to price | raw divided by currency_scale | 5150000000 becomes 51500.0 with currency "IDR" |
| price_before_discount_raw | same scale | 9500000000 becomes 95000.0 |
| variants[].model_id | the per-variant key | 52524008694 - an id space of its own, separate from item_id |
| shop.user_id | not the same number as shop_id | shop 27651338 belongs to user_id 27652722 |
| rating.count_by_star | an array ordered 1 star to 5, summing to count_total | [1, 0, 4, 13, 151], summing to 169, the reported review_count |
There is no keyword search here. Shopee serves no listing data to anyone but its own app, so ids have to come from links, your own catalogue or an affiliate feed.
Real request and response JSON
Captured from the indexed primary action, product, on .
{
"method": "POST",
"url": "https://api.reefapi.com/shopee/v1/product",
"headers": {
"x-api-key": "$REEF_KEY",
"content-type": "application/json"
},
"body": {
"shop_id": 165796339,
"item_id": 4669874676,
"market": "id"
}
}{
"ok": true,
"meta": {
"api": "shopee",
"endpoint": "product",
"mode": "live",
"latency_ms": 2307.5,
"record_count": 1,
"bytes": 936710,
"cache_hit": false,
"market": "id",
"variant_count": 1,
"voucher_count": 0,
"price_available": false,
"removed_fields": [
"product_price.price",
"product_price.price_before_discount",
"product_price.discount"
]
},
"data": {
"product": {
"market": "id",
"market_domain": "shopee.co.id",
"item_id": 4669874676,
"shop_id": 165796339,
"url": "https://shopee.co.id/product/[redacted-phone]/[redacted-phone]",
"canonical_url": null,
"title": "A 81 Herbal Deodorant Spray Natural 60ml bpom",
"description": "No BPOM RI NA [redacted-phone]\nProduk abi herbal ganti Nama jadi A81 herbal\n\nHATI” PRODUK PALSU YG ASLI ADA NO BATCH BARCODE DI KEMASAN DAN BOTOL\n\nproduk fresh selalu ready ya ..\n\nCara penggunaan\n- Hari pertama Sampai dengan 2 Minggu pemakaian, gunakan 2 x sehari pastikan ketiak sudah kering saat mau di semprot abi herbal ya\n- selanjutnya tergantung kebutuhan(note untuk yang bau ketiak nya udh parah tolong bagian ketiak semua baju saat cuci di sikat pakai sabun bagian ketiak nya supaya bau yg lama tidak naik lagi)\n\n-Manfaat abi herbal:\n1. Dapat menghilangkan bau badan, terutama pada bagian ket",
"description_paragraphs": [
{
"type": "text",
"text": "No BPOM RI NA [redacted-phone]"
},
{
"type": "text",
"text": "Produk abi herbal ganti Nama jadi A81 herbal"
},
{
"type": "text",
"text": "HATI” PRODUK PALSU YG ASLI ADA NO BATCH BARCODE DI KEMASAN DAN BOTOL"
}
],
"rich_description_paragraphs": null,
"brand": "A 81 HERBAL",
"brand_id": 3558336,
"condition": "new",
"currency": "IDR",
"currency_scale": 100000,
"item_status": "normal",
"created_at": "[redacted-phone]T07:09:52Z",
"images": [
{
"id": "id-[redacted-phone]ztp-mrl2nuvw1ybm31",
"url": "https://down-id.img.susercontent.com/file/id-[redacted-phone]ztp-mrl2nuvw1ybm31"
},
{
"id": "id-[redacted-phone]ztq-mrfm921ynd3823",
"url": "https://down-id.img.susercontent.com/file/id-[redacted-phone]ztq-mrfm921ynd3823"
},
{
"id": "sg-[redacted-phone]epd6ym9wkv97",
"url": "https://down-id.img.susercontent.com/file/sg-[redacted-phone]epd6ym9wkv97"
}
],
"image_count": 5,
"videos": [],
"categories": [
{
"id": 100630,
"name": "[redacted-name]",
"level": 1
},
{
"id": 102002,
"name": "[redacted-name]",
"level": 2
},
{
"id": 102008,
"name": "Deodoran",
"level": 3
}
],
"frontend_categories": [
{
"id": 11043145,
"name": "[redacted-name]",
"level": 1
},
{
"id": 11043146,
"name": "[redacted-name]",
"level": 2
},
{
"id": 11043152,
"name": "Deodoran",
"level": 3
}
],
"category_id": 100630,
"attributes": [
{
"id": 100016,
"name": "[redacted-name]",
"value": "Paket Hemat",
"value_id": 381
},
{
"id": 100019,
"name": "[redacted-name]",
"value": "Travel Size",
"value_id": 727
},
{
"id": 100036,
"name": "Formulasi",
"value": "Spray",
"value_id": 801
}
],
"variants": [
{
"model_id": 52524008694,
"name": null,
"stock": 10,
"tier_index": [
"[trimmed-depth]"
],
"sku_image_url": null,
"is_pre_order": false,
"estimated_days": 2,
"measurements": null,
"status": 1,
"price": null
}
],
"variant_count": 1,
"variant_options": [
{
"name": null,
"options": [
"[trimmed-depth]"
],
"images": null,
"type": 0
}
],
"stock": 10,
"stock_source": "sum_of_variant_stock",
"shop": {
"shop_id": 165796339,
"location": "KOTA TANGERANG",
"name": null,
"url": "https://shopee.co.id/shop/[redacted-phone]",
"shopee_verified": null,
"official_shop_label": true
},
"shop_vouchers": [],
"seller_services": [
{
"title": "15 Hari Pengembalian",
"description": "Untuk memastikan kepuasanmu, Shopee Mall memberikan periode pengembalian yang lebih panjang (15 hari setelah barang diterima).",
"url": "https://shopee.co.id/m/bebas-pengembalian"
},
{
"title": "100% Original",
"description": "Produk ini dijamin 100% asli dan akan dikirimkan secara langsung. Jika produk yang diterima tidak asli, kamu dapat mengajukan Pengembalian Dana.",
"url": "https://shopee.co.id/m/shopee-garansi-ori"
},
{
"title": "COD-Cek Dulu",
"description": "Bayar pesanan di tempat. Kamu berhak untuk membuka dan memeriksa barang sebelum melakukan pembayaran ke Kurir.",
"url": "https://shopee.co.id/m/tentang-cod-cekdulu"
}
],
"wholesale_tiers": [
{
"min_quantity": 3,
"max_quantity": null,
"price": null
}
],
"size_chart": null,
"logistics": {
"is_pre_order": false,
"estimated_days": 2,
"is_free_shipping": false,
"max_quantity_per_order": null,
"min_purchase_quantity": 1,
"cross_border": false
},
"flags": {
"is_adult": false,
"is_fashion_item": false,
"is_prescription_item": false,
"has_video": false
},
"price": null,
"price_before_discount": null,
"discount": null,
"rating": null,
"review_count": null,
"sold_count": null,
"weight": null,
"dimensions": null,
"shipping": null,
"unavailable": {
"price": "Shopee deletes the price block from the anonymous product page before serving it — its own `removed_fields` manifest lists product_price.price. Use the shop_showcase action for the one item per shop that Shopee still prices publicly.",
"price_before_discount": "Removed by Shopee together with the price on most markets.",
"discount": "Removed by Shopee together with the price.",
"rating": "Removed by Shopee — both product_review.rating_star and item.item_rating are null on the anonymous page.",
"review_count": "Removed by Shopee (cmt_count is null).",
"sold_count": "Removed by Shopee (historical_sold and global_sold are null).",
"stock_total_upstream": "Removed by Shopee. The `stock` field this API returns is the sum of per-variant stock, which Shopee does still publish in full.",
"weight": "There is no weight key anywhere in Shopee's 128-field product schema, on any market. Roughly 40% of products mention a weight in free-text description or attributes and only ~17% carry it as a structured attribute, so it is left to the caller to read `attributes` / `description` rather than reported as a number.",
"dimensions": "There is no length/width/height/dimension key in Shopee's product schema. Same situation as weight — sometimes present as an attribute or in the size chart.",
"shipping": "product_shipping and shipping_info are null on the anonymous page; only the is_free_shipping flag and estimated_days survive (both returned under logistics).",
"reviews": "No review text or histogram exists on this page and the ratings route is gated.",
"related_products": "product_attributes.related_items is an empty list on every product.",
"shop_name": "shop_detailed is null on the product page. The shop action returns the seller's name, rating and metrics for the same shop_id at ~9 KB."
},
"source_removed_fields": [
"product_price.price",
"product_price.price_before_discount",
"product_price.discount"
],
"document_bytes": 936710
}
}
}What the Shopee API does
| Action | Description | Concrete use case | Key params |
|---|---|---|---|
| product | Full Shopee product detail by shop id + item id, or by product link. Title, description, every image, every variant with its own live stock count, variant option axes, attributes, 3-level category path, brand, condition, currency, seller location, product videos with direct MP4 links, and the seller's active voucher codes with their minimum spend. Works the same on all seven markets. Two limits stated up front: Shopee removes PRICE, rating, review count and sold count from the public product page for everyone, so this action returns them as null (the shop_showcase action returns a real live price for one item per shop); and Shopee publishes no weight or dimensions field at all | Pricing teams call product to get full Shopee product detail by shop id + item id, or by product link. | shop_id, item_id, url, market |
| batch | Up to 20 Shopee products in ONE call, fetched in parallel — the same data as the product action, at a lower per-product cost and in roughly the time a single product takes. Each entry succeeds or fails on its own: one dead id does not spoil the call | Marketplace operators call batch to get up to 20 Shopee products in ONE call, fetched in parallel. | items, market |
| shop | Seller profile for a Shopee shop by shop id or shop handle — name, description, logo and cover, country and city, listing count, followers, rating with its good/neutral/bad split, response rate and response time, order preparation time, cancellation rate, official-shop and verified-seller status, and when the shop opened. This is also where the product page's missing shop NAME comes from, and it tells you in advance whether a shop's product pages can be read at all | Catalog enrichment teams call shop to get seller profile for a Shopee shop by shop id or shop handle. | shop_id, username, market |
| shop_showcase | The one product Shopee itself publishes for a shop — WITH a real, live price, discount, rating and sold count. This is the only place a Shopee price is available publicly, and it is shop-addressed, not product-addressed: Shopee picks the item, one per shop. Use it to price-sample a seller, not to price a product you name | Retail analysts call shop_showcase to get the one product Shopee itself publishes for a shop. | shop_id, username, market |
Call product from your stack
curl -X POST https://api.reefapi.com/shopee/v1/product \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"shop_id":165796339,"item_id":4669874676,"market":"id"}'import requests
r = requests.post(
"https://api.reefapi.com/shopee/v1/product",
headers={"x-api-key": REEF_KEY},
json={
"shop_id": 165796339,
"item_id": 4669874676,
"market": "id"
},
)
print(r.json()["data"])const res = await fetch("https://api.reefapi.com/shopee/v1/product", {
method: "POST",
headers: {
"x-api-key": process.env.REEF_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"shop_id": 165796339,
"item_id": 4669874676,
"market": "id"
}),
});
const { ok, data, meta, error } = await res.json();Ask your MCP-connected assistant: call reefapi.shopee.product with {"shop_id":165796339,"item_id":4669874676,"market":"id"}.Who uses this API and why
- Catalogue and brand-protection teams call product to pull an item's full description, images, variants and category path across seven Shopee markets.
- Price-intelligence tools use shop_showcase to read a showcased item's current price, discount percent and sold counts.
- Marketplace analysts use shop to size a seller — item_count, follower_count, rating breakdown and response rate — before ingesting its listings.
- Bulk enrichment pipelines send a list of items to batch and act on the summary totals instead of walking every row.
Questions developers ask before integrating
Why do I need two ids to fetch one Shopee product?
Because that is how Shopee addresses items: a product link is /product/<shop_id>/<item_id>, and the item id alone does not resolve. shop_id is the first number and item_id the second. You can pass the full link instead and both are read out of it, including the share-link form that ends -i.<shop_id>.<item_id>. Ids are also per-market, so the same item_id on shopee.vn is a different product or nothing at all.
Are Shopee prices really multiplied by 100000?
Yes, in Shopee's own storage, and both forms come back so you never have to guess. A measured item returned price_raw 5150000000 with price 51500.0, and price_before_discount_raw 9500000000 with price_before_discount 95000.0, and currency_scale 100000 states the divisor. Use price for display and price_raw only when you are reconciling against another Shopee feed.
Why is the price null on the product action?
Because Shopee strips the price block out of the anonymous product page before serving it. This is not a parse failure and it is not hidden: the response carries source_removed_fields listing exactly what Shopee removed, which on a measured item was product_price.price, product_price.price_before_discount, product_price.discount, product_price.discount_text and display_sections.wholesale, plus an unavailable object explaining each one. For a real price, use shop_showcase.
What can shop_showcase actually be asked for?
A shop, not a product. Shopee publishes exactly one priced item per shop and it chooses which one, so the action takes a shop_id or a username and returns that single item with a live price, discount, rating and sold count. Passing an item id is rejected rather than ignored, because Shopee would ignore it and return the same item anyway, which reads like an answer about the product you named and is not. Use it to price-sample a seller.
Which Shopee discount figure should I trust?
Both are returned because they disagree. On a measured item discount_percent was 46, Shopee's own rounded number matching its "-46%" label, while discount_percent_from_prices was 45.8, computed from 51,500 against 95,000. Use Shopee's figure when you are mirroring what a shopper sees, and the derived one when you are computing margins.
Why is the shop name null on a product response?
The anonymous product page carries the shop id, the location and an official-shop flag but not the shop's display name. Call the shop action with the same shop_id for it, along with the rating split, follower count, response rate and preparation time. A measured shop returned name "Aywears Olshop", 284 listings, 22,165 followers and a rating breakdown of 10,818 good, 337 neutral and 47 bad. Note that shop_id and user_id are different numbers.
What happens to a bad id inside a Shopee batch call?
It fails on its own row and does not spoil the call. A measured batch of three, one of them a made-up item id, returned summary requested 3, ok 2, not_found 1, with the bad row carrying its own NOT_FOUND error object while the two good products came back in full. meta.record_count reported 2, the delivered count, and billing follows that same number rather than what you asked for.
What stock and sales numbers do I actually get?
The product action gives per-variant stock as a real count, with stock_source stating how the product-level figure was reached - sum_of_variant_stock on a measured item totaling 10. shop_showcase is coarser: its stock_raw was 1 alongside in_stock true, so treat that as a flag rather than a count. Sales come from showcase as two separate numbers, sold_recent 129 for the rolling recent window and sold_historical 1000 for the lifetime figure.
What is the Shopee API?
Shopee API is a ReefAPI endpoint group for southeast-asian marketplace products, variants, sellers and shop vouchers. It returns live JSON through POST requests under /shopee/v1.
Is the Shopee API free to try?
Yes. ReefAPI starts with 1,000 free credits, no card required. Shopee calls use the same shared credit balance as every other ReefAPI engine.
Do I need a Shopee login or account?
No login to Shopee is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the Shopee data?
The page example is captured from a live product call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the Shopee API use?
Shopee actions currently cost 1-3 credits per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.
Can I call Shopee from an AI assistant or MCP client?
Yes. Connect ReefAPI once through MCP and your assistant can call shopee actions with the same key, credit pool and JSON envelope used by normal REST requests.