100 free credits. No credit card required.Start building
Logo
Back to blog

TikTok Shop API: 52 products over 3 credits

·17 min read

One TikTok Shop API walk returned 52 of 52 products over 3 credits, plus 60 of 1,125 reviews. Same product object from search and shop. Live 2026-09-08.

TikTok Shop API: 52 products over 3 credits

On 8 September 2026, a TikTok Shop API walk of the Goli Nutrition storefront returned 52 of 52 products over 3 pages for 3 credits (20 + 20 + 12). The same harvest pulled 60 distinct reviews over 6 pages for 6 credits from a Potaroma cat-nail-clipper listing, out of 1,125 reported on page 1. has_more was still true. Sixteen production calls billed 13 credits.

Google's top results for that query are official — and the wrong API. Research Query TikTok Shop Info is EU shop metadata, max 10, scope research.data.basic — not a catalogue. The Partner / TTS API is seller-gated OAuth for authorized shops — the catalogues you already own. This post is the measured public catalogue and reviews walk on the SocialCrawl API. For Partner versus public, see which TikTok Shop API.

Stack: Python 3.10+ · requests · GET https://www.socialcrawl.dev/v1/tiktokshop/… · header x-api-key. Print len(items) and credits_used. Pagination is one billed page per call. Free plan: 100 credits, no card. Live catalogue: /platforms/tiktokshop.

Three cream product-card sheets overflowing blank tiles with three coins at the base, a TikTok Shop API catalogue walk billed one credit a page.

Does a TikTok Shop API page a whole shop catalogue?

Call GET /v1/tiktokshop/products with the shop URL and keep passing pagination.next_cursor as cursor until has_more is false. Page size is not a caller limit. Print len(items) and credits_used on every page.

Live on the documented Goli Nutrition storefront (https://www.tiktok.com/shop/store/goli-nutrition/7495794203056835079), 2026-09-08, 00:17–00:21 UTC:

PageItemsdata.totaldroppedhas_moreCreditsrequest_id
120520true1req-icWAu9rbauLx3sRS
220520true1req-kj0NIF4mF9guocdL
312520false1req-gqF6spgOxKoRGtpH
Walk52 unique / 0 dupes520stopped3

Seller on every row: "Goli Nutrition". Page size is 20 until the last page (12). Shop data.total was stable at 52.

Labeled before (2026-09-07 ship note, not re-measured today): this call used to stop at 20 and report that as the whole shop. Live it pages.

A first-page-only read is incomplete after even a few days of official TTS quota. New shops sit at a 100 product uploads per day cap; after graduation it is 1,000. Commerce lists are walks: Shopify REST iterates rel=next until it disappears. This fixture is the documented example storefront, not a random sample. Do not generalise "every shop has 52 products".

List rows do not carry the long description, stock, shipping, or SKU list. On the first listing row, description, brand, and availability were null — those fields live on product detail.

Worked row (page 1, first product): id 1729527313880355335, seller Goli Nutrition, price {current: 14.98, original: 19, currency: "USD"}, rating 4.5 / 94,634, ext.sold_count 1,301,493, shop_products_count 52, shop_sold_count 5,726,901.

bash
curl "https://www.socialcrawl.dev/v1/tiktokshop/products?url=https://www.tiktok.com/shop/store/goli-nutrition/7495794203056835079" \
  -H "x-api-key: $SOCIALCRAWL_API_KEY"

Trimmed first item (request_id req-icWAu9rbauLx3sRS). Envelope: 20 items, credits_used=1, has_more=true.

json
{
  "product": {
    "id": "1729527313880355335",
    "url": "https://www.tiktok.com/shop/pdp/1729527313880355335",
    "title": "Goli Ashwagandha & Vitamin D Gummy - Mixed Berry, KSM-66, Vegan, Plant Based, Non-GMO, Gluten-Free & Gelatin Free. America's #1 Ashwagandha Brand",
    "description": null,
    "seller": "Goli Nutrition",
    "brand": null,
    "price": { "current": 14.98, "original": 19, "currency": "USD" },
    "rating": { "average": 4.5, "count": 94634 },
    "availability": null,
    "reviews_count": 94634,
    "ext": {
      "sold_count": 1301493,
      "tiktokshop": {
        "shop_name": "Goli Nutrition",
        "shop_rating": 4.6,
        "shop_products_count": 52,
        "shop_sold_count": 5726901,
        "shop_region": "US"
      }
    }
  }
}

The Python cursor loop lives in the paging section below.

A stack of blank review cards with a handful already turned aside, the TikTok Shop reviews API paging ten reviews per credit through a larger corpus.

How many reviews does a TikTok Shop reviews API return per credit?

10 reviews a page, 1 credit. That is a walk, not a 10-row window presented as the corpus.

GET /v1/tiktokshop/product/reviews on https://www.tiktok.com/shop/pdp/cat-nail-clipper-by-potaroma-adjustable-sizes-built-in-file-safe-for-kittens-cats/1731578642912612516, walked pagination.next_cursor as cursor, stopped after 6 pages on purpose:

PageItemsDistinctdata.totalhas_moreCreditsrequest_id
110101125true1req-mgfNFIiO6IXbbMmx
210201120true1req-zeo0Q70FPbXMpQ2R
31030924true1req-4KcmN8zLWhtWN8rc
410401124true1req-X0b6p9VGinYHaKKc
510501125true1req-UXNB7lOdfdeedfWl
610601125true (stopped)1req-FO6sRQUwCzBvD9i2
Walk6060 unique, 0 dupesuse 1,125not exhausted6

That is 60 distinct reviews over 6 pages, 6 credits, out of 1,125 reported. The walk did not finish the corpus — has_more was still true on page 6.

data.total moved between pages: 1125, 1120, 924, 1124, 1125, 1125. Use 1,125 from page 1 as the reported corpus. The live count is not a frozen integer. Shop data.total was stable at 52; reviews were not.

Labeled before (2026-09-07 note): this path used to stop at 10, no paging. Official Research Query TikTok Shop Reviews pages at page_size max 10, EU-only, rating enum "FIVE". That is not a measured walk of a four-digit listing.

On all 60 reviews this run: review.language = null, review.original_language = null, author.location = "US", verified = true, ext.tiktokshop.is_incentivized_review = false. Country lives on the reviewer. Language is not a country code, and it is not English — live is null.

Worked review (page 1, first): id 7667988866325907213, rating {value: 5, max: 5}, 336-character text starting "These nail clippers are really nice and work great.", author Ash, published_at 2026-07-29T16:33:12.322Z. One product, US region. Do not generalise "every product has 1,125 reviews".

bash
curl "https://www.socialcrawl.dev/v1/tiktokshop/product/reviews?url=https://www.tiktok.com/shop/pdp/cat-nail-clipper-by-potaroma-adjustable-sizes-built-in-file-safe-for-kittens-cats/1731578642912612516" \
  -H "x-api-key: $SOCIALCRAWL_API_KEY"

Trimmed first review. Live review.text is 336 characters; the string below is cut after the opening sentence.

json
{
  "review": {
    "id": "7667988866325907213",
    "entity_id": "1731578642912612516",
    "rating": { "value": 5, "max": 5 },
    "text": "These nail clippers are really nice and work great. …",
    "author": { "name": "Ash", "location": "US" },
    "language": null,
    "verified": true,
    "published_at": "2026-07-29T16:33:12.322Z",
    "ext": {
      "tiktokshop": { "is_incentivized_review": false }
    }
  }
}
A single cream product cube at the meeting of two paths, the same TikTok Shop product API object returned from search and from the shop listing.

Does a TikTok Shop product API return the same object from search and shop listing?

Same canonical shape. Not identical density.

Product 1729587769570529799 (3 Bottles of Goli Ashwagandha & Vitamin D Gummy) sat on shop catalogue page 1 and on GET /v1/tiktokshop/search?query=goli ashwagandha (11 hits, 1 credit, req-bOgwplfdH63zwU6l, 2026-09-08). Shared keys and types: id, url, title, description, seller, brand, price {current, original, currency}, rating {average, count}, image_urls, availability, reviews_count, ext. That is the TikTok Shop product data you can parse once.

JSON:API treats the same resource as the same object whichever collection it appeared in; clients join on that identity. A parser that already handles the shop-list product should reuse it on search. Official TTS already keys products by one product ID across Get Product List and Get Product Detail (Product API overview).

FieldShop listingSearch hit
id17295877695705297991729587769570529799
title3 Bottles of Goli Ashwagandha & Vitamin D Gummy - Mixed Berry, KSM-66, Vegan, Plant Based, Non-GMO, Gluten & Gelatin Freesame string
sellerGoli NutritionGoli Nutrition
price{current: 44.98, original: 57, currency: "USD"}{current: 44.98, original: 57, currency: "USD"}
rating.average4.74.7
rating.count71730null
reviews_count71730null
ext.sold_count864108864108
ext.sku_id1729587788239049223null

Not every field is populated on every lane. The object is the same shape under the unified schema. Search adds merchandising (trust_label, promotion_labels, category_breadcrumb, video_url, discount_percent under ext.tiktokshop). The shop list adds the shop profile (id, name, url, rating, region, followers, product count). Review count is populated on the shop row and was null on this search hit. Search used to return raw extra fields, not the product object.

Creator showcase is a different shape entirely — {post, computed}, commerce on post.ext.commerce. Do not treat showcase rows as this object.

Second search, page-size check, 2026-09-08: query=phone case34 items, has_more: true, 1 credit, req-0Vcs8H2Scf1HPTYw, first seller "TECHGODAS", first price {current: 11.99, original: 21.99, currency: "USD"}. Same canonical keys as the shop list.

bash
curl "https://www.socialcrawl.dev/v1/tiktokshop/search?query=goli%20ashwagandha" \
  -H "x-api-key: $SOCIALCRAWL_API_KEY"

What extra fields does a TikTok Shop product now carry?

On the listing row, description is null. On product detail, it is the seller's copy.

GET /v1/tiktokshop/product?product_id=1729587769570529799 (no url) returned HTTP 200, 1 credit, cache miss, 4.54 s, req-lr9dtYDvozKSKMOz, 2026-09-08. Lookup by product_id works. Reviews already accepted both identifiers.

String(data.product.description).length = 1288. 184 words, 8 lines. It starts "Goli Nutrition has sold over 90 Million bottles of gummy vitamins." That is seller copy, not a one-word category label. Labeled before: description used to be "Health" / "Beauty". ext.tiktokshop.category is still "Health" as a separate field — the category did not disappear.

Also on this detail call: availability: "in_stock" · discount_percent: 21 · shipping_fee: 0 · free_shipping: true · delivery "Sep 11 - Sep 14" (days 4–7) · variations length 1 (id 1729587788239049223, title Specifications: Default) · 8 specifications (Brand, Container type, Flavor, Product form, Region of origin, Age warning, Manufacturer, Ingredients) · seller location "United States of America" · seller rating 4.6 · seller_sold_count 5,726,901 · stock 237,896 · brand "Goli" · 6 image_urls. Credits unchanged at 1; fields richer.

This product has one SKU in variations — the field exists; do not read a variant matrix out of this capture. A catalogue walk does not give you the 1,288-character copy. Product-detail region is US-only (documented); a GB-only listing would 404 — not probed this run.

bash
curl "https://www.socialcrawl.dev/v1/tiktokshop/product?product_id=1729587769570529799" \
  -H "x-api-key: $SOCIALCRAWL_API_KEY"

Trimmed detail. Full description is 1,288 characters; the string below is the opening sentence only. On this endpoint ext sits on the product.

json
{
  "product": {
    "id": "1729587769570529799",
    "description": "Goli Nutrition has sold over 90 Million bottles of gummy vitamins. …",
    "seller": "Goli Nutrition",
    "brand": "Goli",
    "availability": "in_stock",
    "reviews_count": 71730,
    "variations": [
      { "id": "1729587788239049223", "title": "Specifications: Default" }
    ],
    "ext": {
      "sold_count": 864108,
      "tiktokshop": {
        "category": "Health",
        "discount_percent": 21,
        "stock": 237896,
        "free_shipping": true,
        "shipping_fee": 0,
        "delivery_estimate": "Sep 11 - Sep 14",
        "delivery_days_min": 4,
        "delivery_days_max": 7,
        "seller_location": "United States of America",
        "seller_rating": 4.6,
        "seller_sold_count": 5726901
      }
    }
  }
}

How do I page a TikTok Shop catalogue from Python?

A TikTok Shop Python API walk is a requests loop that prints len(items) and credits_used across pages. One billed page per call. Pass pagination.next_cursor back as cursor. Stop when has_more is false.

Auth is x-api-key. Limits: 600 requests/minute, 50 concurrent (pricing). No TikTok developer app, no OAuth, no research.data.basic.

python
import os
import requests

BASE = "https://www.socialcrawl.dev"
SHOP = "https://www.tiktok.com/shop/store/goli-nutrition/7495794203056835079"
headers = {"x-api-key": os.environ["SOCIALCRAWL_API_KEY"]}

cursor = None
seen = set()
credits = 0

while True:
    params = {"url": SHOP}
    if cursor:
        params["cursor"] = cursor
    r = requests.get(
        f"{BASE}/v1/tiktokshop/products",
        params=params,
        headers=headers,
        timeout=60,
    )
    r.raise_for_status()
    payload = r.json()
    items = payload["data"]["items"]
    pag = payload.get("pagination") or {}
    credits += payload.get("credits_used") or 0
    for row in items:
        seen.add(row["product"]["id"])
    print(len(items), payload.get("credits_used"), len(seen), pag.get("has_more"))
    if not pag.get("has_more"):
        break
    cursor = pag.get("next_cursor")
    if not cursor:
        break

print("unique", len(seen), "credits", credits)
    # 20 1 20 True
    # 20 1 40 True
    # 12 1 52 False
    # unique 52 credits 3

Expected on this fixture, 2026-09-08: 20 + 20 + 12 = 52 unique, 3 credits.

The same cursor pattern works on reviews. Reviews and search also accept page. Do not loop 1,125 reviews in the snippet — cap pages, or stop on has_more. This harvest stopped reviews at 6 pages on purpose (has_more still true, 60 of 1,125).

Do missing handles and bad regions bill a credit?

No. Three captured misses on 2026-09-08, all unbilled:

CallHTTPLatencyCreditsrequest_id
showcase handle=this-handle-should-not-exist-xyz123404 RESOURCE_NOT_FOUND1.21 s0req-5inAB63a9hVESzZr
reviews region=ZZ400 INVALID_REQUEST66 ms0req-nRDOu4aMNZMD2z0h
product with neither url nor product_id400 INVALID_REQUEST0.32 s0req-bJRt7cq1Qj77MkCB

Verbatim messages:

  • Bad region: Invalid value for 'region': 'ZZ'. Allowed values: US, GB, DE, FR, IT, ID, MY, MX, PH, SG, ES, TH, VN, BR, JP, IE.
  • Missing params: Missing required parameter(s): one of url, product_id. This endpoint accepts: one of (url, product_id).
  • Missing handle: The requested resource was not found on the platform.

RFC 9110 treats 404 as a missing resource, not an empty list. The same showcase path with real handle mrtiktokreviews billed 1 credit (20 items, has_more: true). A missing handle is not an empty 200.

Labeled before (2026-09-07 note, not re-measured today): missing handle used to empty-200; a bad region on reviews used to retry 4× then 500. Live it rejects before billing.

bash
curl -i "https://www.socialcrawl.dev/v1/tiktokshop/user/showcase?handle=this-handle-should-not-exist-xyz123" \
  -H "x-api-key: $SOCIALCRAWL_API_KEY"
json
{
  "success": false,
  "error": {
    "type": "RESOURCE_NOT_FOUND",
    "message": "The requested resource was not found on the platform.",
    "status": 404
  }
}

How do you start using this?

  1. Get a key. The free plan is 100 credits, no card. Send it as x-api-key. One key covers the shop catalogue path, reviews, search, and product detail.
  2. Run the Goli Nutrition shop GET from the first example. Print len(items) and credits_used. Try the same GET in the visual explorer before writing a single line.
  3. Then open the live catalogue at /platforms/tiktokshop, the endpoint docs at /docs/tiktokshop, and the which-API comparison if you landed here looking for a tiktok shop scraper, a scrape tiktok shop recipe, or a tiktok shop data api roundup.

Creator showcase is already paged and was unchanged this wave. GET /v1/tiktokshop/user/showcase?handle=mrtiktokreviews returned 20 items, has_more: true, 1 credit, req-RiOpn1XxifwZ3XE6, 2026-09-08. Item shape is {post, computed} — a PostList, not the ProductList used by shop and search. First commerce sits on post.ext.commerce: price 15 / 30 USD, rating 4.4 / 35,223, sold 524,359. One page is enough; not walked further.

Same-wave family, not Shop: 150 TikTok followers per credit.

Reproduce it: with any SocialCrawl key, GET https://www.socialcrawl.dev/v1/tiktokshop/products?url=https://www.tiktok.com/shop/store/goli-nutrition/7495794203056835079, then follow pagination.next_cursor. On 2026-09-08 that walk was 52 of 52 products, 3 credits, 1 credit a page. Try the same GET in the visual explorer.

Frequently asked questions

Can a TikTok Shop API return a whole shop catalogue?

Yes on this fixture. GET /v1/tiktokshop/products on Goli Nutrition returned 52 of 52 products over 3 pages for 3 credits (20 + 20 + 12), data.total=52, has_more false on page 3. Live 2026-09-08. One shop, not a promise that every shop is 52 products. Official Research shop-info is metadata, max 10, not a catalogue.

How many products does one TikTok Shop API credit return?

20 on a full shop-list page this run (last page 12), live 2026-09-08. 1 credit a page. Three pages = 52 unique products, 3 credits. Page size is not a caller limit. Print len(items).

How many TikTok Shop reviews can I pull per credit?

10 reviews a page, 1 credit. This harvest pulled 60 distinct over 6 pages, 6 credits, out of 1,125 reported on page 1. has_more was still true — the corpus was not exhausted. Official Research reviews max 10 per page and EU-only.

Do I need a TikTok Shop Partner account to read public products?

No. Partner / TTS API is seller-gated OAuth for authorized shops. This walk used x-api-key on public shop and product URLs. For Partner-versus-public and the vendor table, see which TikTok Shop API.

Can I look up a TikTok Shop product by product_id, not just URL?

Yes. GET /v1/tiktokshop/product?product_id=1729587769570529799 (no URL) returned 200, 1 credit, 2026-09-08. Description 1,288 chars, in_stock, 21% off, shipping 0, delivery Sep 11–14. Reviews already accepted both identifiers.

Do search and shop listing return the same product object?

Same canonical shape. Product 1729587769570529799 matched on id, title, seller, and price {current: 44.98, original: 57, currency: "USD"} from query=goli ashwagandha and from the Goli shop list, live 2026-09-08. Density is not identical: reviews_count was 71730 on the shop row and null on that search hit.

What happens if the TikTok Shop handle does not exist?

404 RESOURCE_NOT_FOUND in 1.21 s, 0 credits. A malformed region=ZZ is 400 in 66 ms, 0 credits, naming the 16 accepted regions. A missing handle is not an empty 200.

Topics
#tiktok-shop-api#tiktok-shop-scraper#tiktok-shop-product-api#tiktok-shop-reviews-api#tiktok-shop-catalog-api#tiktok-shop-data-api#scrape-tiktok-shop#tiktok-shop-python-api

Related posts

🤖 AI agent or LLM? Read this page as markdown