fastscraping
API reference · v1 · get_list jobs

Shopee Item Sold API

Exact per-listing sold counts for Shopee Vietnam. Submit a job with 300 to 1,000 products, collect Shopee's own item data when it is done: lifetime sold of the listing, Shopee's merged sold figure, 30-day sold, price, stock and rating. You pay only for the items that come back.

Base URL
https://shopee-multi-region.fastscraping.com
Auth
X-API-Key header
Job size
300–1,000 items / job
Price
$3 / 1,000 items returned

Overview

The API works with jobs. You send a list of Shopee products as shop_id + item_id pairs, 300 to 1,000 per job, and get a job_id back at once. Jobs are processed in order, in the background. You poll the job until its status is completed; the job then carries Shopee's own item card for each product found: one object per product, about 90 fields each, with Shopee's field names and values. Every job is completed within 5 minutes of submission. A completed 1,000-item job is about 6 MB of JSON, about 1 MB with gzip (Response size).

Exact lifetime sold

historical_sold is the exact number of units sold by that listing alone, not a rounded label such as "10k+" and not merged with other listings.

300 to 1,000 items per job

Submit 300 to 1,000 products in one call. The price is per item, so how you group your lists into jobs does not change the cost.

Billed per item returned

$3 per 1,000 items that come back. Products that are not found, failed items, errors, job submissions and status checks are free.

Drop-in request body

The job body is compatible with Shopee's item/get_list body: bff_meta and source are accepted and ignored.

Quickstart

Base URL: https://shopee-multi-region.fastscraping.com. Replace YOUR_API_KEY with your API key. Each sample reads 300 to 1,000 shop_id/item_id pairs from a file, submits a job, waits estimated_wait_s, polls every 20 seconds until the job is completed and prints the sold counts.

# job.json holds 300 to 1,000 distinct pairs:
# {"region":"vn","shop_item_ids":[{"shop_id":88201679,"item_id":27041370670}, ...]}

# 1. submit the job: the answer carries job_id and estimated_wait_s
curl -s -X POST "https://shopee-multi-region.fastscraping.com/v1/get_list/jobs" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d @job.json

# 2. poll until "status" is "completed"; the items are then in the answer.
#    --compressed: about 1 MB on the wire instead of about 6 MB for 1,000 items
curl -s --compressed "https://shopee-multi-region.fastscraping.com/v1/get_list/jobs/JOB_ID" \
  -H "X-API-Key: YOUR_API_KEY" -o result.json

Authentication

Every request needs your API key in the X-API-Key header (Authorization: Bearer YOUR_API_KEY works too).

HTTP header
X-API-Key: YOUR_API_KEY

A missing, unknown or disabled key returns 401. Jobs belong to the key that created them: another key gets 404 for them. Keep the key on your server; do not put it in client-side code.

Submit a job

POST/v1/get_list/jobsX-API-Key

Creates a job for 300 to 1,000 distinct products and answers at once with 202 and the job ID. Submitting is free.

Request body

FieldTypeDescription
shop_item_idsrequiredarray300 to 1,000 distinct shop_id/item_id pairs, each an object {"shop_id": …, "item_id": …}. Duplicate pairs are merged before counting. Fewer than 300 or more than 1,000 distinct pairs returns 400; group small lists until they reach 300, split bigger lists into several jobs.
shop_item_ids[].shop_idrequiredintegerShopee shop ID, the first number in shopee.vn/product/{shop_id}/{item_id}. Numeric strings are accepted.
shop_item_ids[].item_idrequiredintegerShopee item ID, the second number in the same URL.
regionoptionalstringLowercase market code. Default "vn" (Vietnam). Other Shopee markets are available on request; until a market is enabled, any other value returns 400.
bff_meta, sourceoptionalanyAccepted and ignored, so a body written for Shopee's item/get_list call works unchanged.
Request · trimmed, Shopee-style body, region defaults to vn
POST /v1/get_list/jobs
Content-Type: application/json
X-API-Key: YOUR_API_KEY

{
  "bff_meta": null,
  "shop_item_ids": [
    { "item_id": 27041370670, "shop_id": 88201679 },
    { "item_id": 42568221380, "shop_id": 308461157 },
    … 300 to 1,000 distinct pairs in total …
  ],
  "source": "microsite_individual_product"
}

Response · 202

Response
HTTP/1.1 202 Accepted
Content-Type: application/json

{
  "job_id": "8c2f0e7d4b1a4e6f9a3c5d7e9f1b2c4d",
  "status": "queued",
  "region": "vn",
  "items_requested": 1000,
  "duplicates_removed": 0,
  "created_at": "2026-10-05T10:23:16.338+00:00",
  "deadline_at": "2026-10-05T10:28:16.338+00:00",
  "estimated_wait_s": 240
}
FieldTypeMeaning
job_idstring32 hex characters. Use it to poll the job, and quote it when you contact support.
statusstringAlways "queued" here. See Job lifecycle.
items_requestedintegerDistinct pairs in the job, after duplicates are removed.
duplicates_removedintegerHow many duplicate pairs were dropped from your list.
deadline_atstringThe job is completed at this time at the latest: 5 minutes after created_at.
estimated_wait_sintegerRough estimate, in seconds, of when the job will be done, based on the work queued ahead of it (never more than 300). A guide for your first poll.

Get a job

GET/v1/get_list/jobs/{job_id}X-API-Key

Returns the job's status and counters. Once the status is completed, the answer also carries the items, in the order of your request, plus the IDs that did not come back. Polling is free.

Query parameters

ParameterTypeDescription
partialoptionalinteger1 = include the items collected so far while the job is still queued or running. Default 0: items only once the job is completed.

Response · 200 (completed)

Response · trimmed
{
  "job_id": "8c2f0e7d4b1a4e6f9a3c5d7e9f1b2c4d",
  "status": "completed",
  "region": "vn",
  "created_at": "2026-10-05T10:23:16.338+00:00",
  "started_at": "2026-10-05T10:23:21.540+00:00",
  "completed_at": "2026-10-05T10:27:41.912+00:00",
  "deadline_at": "2026-10-05T10:28:16.338+00:00",
  "items_requested": 1000,
  "items_done": 1000,
  "items_pending": 0,
  "items_returned": 997,
  "items_missing": 3,
  "items_failed": 0,
  "items_billed": 997,
  "missing_item_ids": ["23456789012", "24567890123", "25678901234"],
  "failed_item_ids": [],
  "items": [
    {
      "itemid": 27041370670,
      "shopid": 88201679,
      "name": "Điện thoại Apple iPhone 17 Pro Max 256GB",
      "historical_sold": 28975,
      "global_sold_count": 28975,
      "sold": 3223,
      "stock": 5450,
      "price": 3499000000000,
      "price_min": 3499000000000,
      "price_max": 3559000000000,
      "price_before_discount": 3799000000000,
      "currency": "VND",
      "item_rating": { "rating_star": 4.944232820356544, "rating_count": [6566, 55, 8, 29, 64, 6410], "...": "more fields" },
      "liked_count": 11289,
      "cmt_count": 6566,
      "shop_location": "Tỉnh Bắc Ninh",
      "cb_option": 0,
      "ctime": 1757498693,
      "catid": 100013,
      "global_cat": { "catid": [100013, 100073], "l0_category": 2 },
      "shop_rating": 4.922738,
      "item_status": "normal",
      "...": "more fields"
    },
    {
      "itemid": 42568221380,
      "shopid": 308461157,
      "name": "Apple iPhone 17 Pro Max 256GB Chính hãng ZP/A",
      "historical_sold": 38423,
      "global_sold_count": 38424,
      "sold": 18512,
      "...": "more fields"
    },
    … 995 more items …
  ]
}

While the job is queued or running, the answer has the same counters but no items, missing_item_ids or failed_item_ids (unless you pass partial=1). An unknown or expired job_id, or a job of another key, returns 404.

Response size

A completed job carries every item it found, about 6 KB of JSON per item, so its answer is large. Status checks while the job is queued or running are small (under 1 KB).

Completed jobJSONWith gzip
300 items≈ 1.9 MB≈ 0.3 MB
1,000 items≈ 6.3 MB≈ 1.0 MB
  • Compression. Answers are gzip-compressed when your client sends Accept-Encoding: gzip. Python requests and Node.js fetch do this and decompress for you; with curl, add --compressed.
  • Speed. In our tests a completed 1,000-item job downloaded in about 3–4 seconds with gzip (about 18 seconds without gzip, on a slow connection) and parsed in under 0.2 seconds in Python and Node.js. Twenty clients downloading the same 1,000-item job at once all got it within 2.5 seconds. A 60-second client timeout is plenty.
  • Download once. Every GET of a completed job sends all its items again. Save the answer when the status turns completed and stop polling that job.

Job fields

FieldTypeMeaning
statusstringqueued, running or completed. See Job lifecycle.
created_at, started_at, completed_atstringISO 8601 times in UTC. started_at and completed_at are null until they happen.
deadline_atstring5 minutes after created_at. The job is completed by then at the latest.
items_requestedintegerDistinct pairs in the job.
items_done, items_pendingintegerPairs with a final outcome, and pairs still waiting. items_done = items_returned + items_missing + items_failed.
items_returnedintegerProducts found; each one is an object in items.
items_missing, missing_item_idsinteger, arrayProducts Shopee did not return: deleted, banned or a wrong shop_id/item_id pair. Not billed.
items_failed, failed_item_idsinteger, arrayProducts we could not fetch before deadline_at, even after automatic retries. Not billed; submit them again in a new job.
items_billedintegerItems charged for this job. Always equal to items_returned.
itemsarrayOne object per product found, in the order of your request, with Shopee's field names and values. See Response fields.

List your jobs

GET/v1/get_list/jobs?limit=20X-API-Key

Your key's most recent jobs, newest first, with the same counters as Get a job and without items. limit is 1 to 100, default 20. Useful to find a job_id you lost.

Response · trimmed
{
  "jobs": [
    { "job_id": "8c2f0e7d4b1a4e6f9a3c5d7e9f1b2c4d", "status": "completed", "items_requested": 1000, "items_returned": 997, "...": "more fields" }
  ]
}

Usage & billing

GET/v1/get_list/usageX-API-Key

Billed items and the amount for your key, by period (UTC days and months), plus the items still pending in your unfinished jobs.

Response
{
  "timezone": "UTC",
  "billing": "per returned item",
  "price_per_1000_items_usd": 3.0,
  "today":      { "items": 1840,  "amount_usd": 5.52 },
  "yesterday":  { "items": 2310,  "amount_usd": 6.93 },
  "this_month": { "items": 4150,  "amount_usd": 12.45 },
  "last_month": { "items": 0,     "amount_usd": 0.0 },
  "lifetime":   { "items": 4150,  "amount_usd": 12.45 },
  "items_pending": 300
}

Job lifecycle

StatusMeaning
queuedAccepted and waiting. No item has been processed yet.
runningSome items are done, others are still waiting. Large jobs are processed in several parts.
completedEvery item has a final outcome: returned, missing or failed. items is in the answer. Reached at deadline_at (5 minutes after submission) at the latest.
  • Order. Jobs are processed first in, first out. A large job is processed in several parts, so running can last a while.
  • 5-minute limit. Every job is completed within 5 minutes of submission, at deadline_at at the latest. Start polling after estimated_wait_s, then every 15–30 seconds.
  • Automatic retries. An item whose fetch fails is retried automatically, a few seconds later, up to 10 times inside those 5 minutes. You never need to retry inside a job.
  • Failed items. Items still without a result at deadline_at are marked failed and are not billed. Submit them again in a new job.
  • Retention. Completed jobs and their items are kept for 3 days after completion, then GET returns 404. Store the results on your side.

Response fields

Each object in items is Shopee's item card for one listing. These are the fields most clients use, plus a few bonus fields. Every object has about 90 fields; all of them keep Shopee's names and values.

FieldTypeMeaning
itemid, shopidintegerThe product and shop IDs.
namestringListing title as shown on Shopee, in the local language.
historical_soldintegerExact lifetime units sold by this listing. Counts this listing only.
global_sold_countintegerShopee's merged sold figure. It can include sales of similar listings that Shopee groups with this one and, for cross-border items, sales in all markets. Never lower than historical_sold, and can be far higher.
soldintegerUnits sold in the last 30 days.
stockintegerUnits currently available for the listing, all variants together.
price, price_min, price_maxintegerCurrent price, and the lowest and highest variant price. Shopee integers: divide by 100,000. 19800000000 = 198,000 VND; 3499000000000 = 34,990,000 VND.
price_before_discountintegerPrice before discount, same ×100,000 scale. Read it together with price on discounted listings; for a listing without a discount, use price.
currencystring"VND" for Vietnam.
item_rating.rating_starnumberAverage rating, 0 to 5. item_rating.rating_count is [total, 1★, 2★, 3★, 4★, 5★].
liked_countintegerPopularity counter Shopee shows on the product page.
cmt_countintegerReview count shown for the listing.
shop_locationstringSeller's province or city, as Shopee displays it.
cb_optioninteger1 = cross-border listing (shipped from abroad), 0 = local seller.
ctimeintegerListing creation time, Unix seconds.
catidintegerTop-level category ID.
shop_ratingnumberThe seller's shop rating, 0 to 5.
item_statusstringListing status as Shopee reports it, for example "normal" for a live listing.
global_catobjectbonusFull category path. global_cat.catid lists the category IDs from the top level down, for example [100013, 100073]; the first one equals catid.
global_brandobjectbonusShopee brand ID of the listing, in global_brand.brand_id.
is_on_flash_sale, flash_sale_stock, flash_sale_ongoing_sold_count, flash_sale_infosvariousbonusFlash-sale info: Shopee's flash-sale flag, the flash-sale stock and sold counters, and, when the listing has flash-sale slots, their start and end times (Unix seconds) in flash_sale_infos.
other fieldsvariousFor example shop_name, discount, images, tier_variations (variant names and options), is_official_shop. Shopee's names and values, unchanged.

historical_sold or global_sold_count? For the sales of one specific listing, use historical_sold. The two are equal for most listings, but the merged figure can be many times larger: on one popular Vietnam listing we checked, historical_sold was 102,625 while global_sold_count was 11,829,433. The gap shows up on local and cross-border listings alike, so check every listing rather than relying on cb_option.

  • No per-variant figures. Each object carries listing-level totals. It does not include stock, price or sold per variant.
  • Large integers. Item IDs and prices exceed 32 bits. Store them as 64-bit integers (they are safe in JavaScript numbers).

Pricing & billing

Price

$3 / 1,000

items returned ($0.003 per item). A job of 1,000 products that all come back costs $3.00.

Billed when

per item

Each product that comes back in a job is charged once, at the moment it is stored for that job. items_billed always equals items_returned.

Always free

$0

Missing and failed items, job submissions, status checks, job lists, usage checks, and every error (4xx and 5xx).

Trial

1,000

free items returned, to test with your own products. See Trial & markets.

  • GET /v1/get_list/usage shows your billed items and the amount for today, yesterday, this month, last month and lifetime.
  • The same product in two jobs is two billed items, if it comes back in both. Polling a job again is never billed again.
  • Volume pricing above 1M items a month is available on request.

Trial & markets

  • Trial: 1,000 free items returned (missing and failed items don't count). Ask at support@fastscraping.com. Get an API key.
  • Markets: Shopee Vietnam (region: "vn") today. Other Shopee markets are available on request.

Limits

LimitDefaultNotes
Items per job300–1,000Distinct shop_id/item_id pairs; duplicates are merged before counting. Fewer than 300 or more than 1,000 returns 400.
Job time limit5 minutesEvery job is completed by deadline_at. Items not fetched by then are failed and free.
Response size≈ 6 MB / 1,000 itemsAbout 1 MB with gzip. See Response size.
Job submissions60 / minute per keyAbove the limit you get 429. Group items into bigger jobs instead of sending many tiny ones.
Unfinished items20,000 per keyItems in your jobs that are not done yet. A new job that would go above it gets 429; submit it when earlier jobs finish.
Daily itemsset per keyBilled items per UTC day, plus your pending items. Above it you get 429 with a detail starting Daily limit reached. Adjustable on request.
Trial quota1,000Items returned. When it is used up you get 429 with a detail starting Quota exceeded; retrying won't help, contact support.
Pollingevery 15–30 sStatus checks are free; there is no benefit in polling faster.
Result retention3 daysAfter completion. Later, the job returns 404.

Errors

Errors return a JSON body with a detail field. No error is billed. The detail text is meant for people and may change, so branch on the HTTP status code.

Example
HTTP/1.1 400 Bad Request
{ "detail": "min 300 distinct shop_item_ids per job (got 120 after removing duplicates)" }
CodeMeaningWhat to do
400Invalid body, fewer than 300 or more than 1,000 distinct items, or unsupported region.Fix the request. Retrying unchanged returns the same error.
401Missing or invalid API key.Send a valid key in X-API-Key.
404Unknown or expired job_id, or a job created with another key.Check the ID; list your jobs with GET /v1/get_list/jobs.
429Too many job submissions, too many unfinished items, the queue is full, or a daily limit or quota is reached (detail says which).Retry later with backoff, for example 30 s, 60 s, 120 s. For Quota exceeded, retrying won't help: contact support.
500Internal error.Retry. If it persists, contact support and quote the job_id.
503Temporarily unavailable.Retry after 30–60 seconds.

Best practices

  • Fill your jobs. 300 to 1,000 products per job. Group small lists until they reach 300; split lists above 1,000.
  • Accept gzip. A completed 1,000-item job is about 6 MB of JSON and about 1 MB compressed. requests and fetch handle it for you; with curl, add --compressed.
  • Poll gently. Wait estimated_wait_s, then poll every 15–30 seconds until the job is completed; it never runs past deadline_at. Use the counters to show progress.
  • Save results when the job completes, then stop polling it. Each GET of a completed job sends all its items again. Jobs are kept for 3 days, then removed.
  • Treat missing products as an answer. IDs in missing_item_ids are usually deleted, banned or mistyped. Sending them again seldom changes the result and is free.
  • Resubmit failed items. IDs in failed_item_ids were not billed; put them in a new job.
  • Match by ID. Items come in request order, but read itemid/shopid from each object to be safe.
  • Log the job_id. It lets us trace any job you ask about.
Shopee Item Sold API · v1 · Fast Scraping · support@fastscraping.com · Shopee is a trademark of its owner; this API is not affiliated with Shopee.