TikTok Shop
GET /v1/tiktok-shop/product-details

TikTok Shop Product Details API

PDP — price (sku_min when guest min is *), sold vs stock, seller id/url, images[]. Unresolved URL is 404 at 0 credits.

2 credits per request
TL;DR
PDP — price (sku_min when guest min is *), sold vs stock, seller id/url, images[]. Unresolved URL is 404 at 0 credits. The TikTok Shop Product Details API (TikTok Shop) is a single authenticated GET request to /v1/tiktok-shop/product-details that responds with clean JSON and costs 2 credits. Pass cache=true for a free 24h cache hit; default is always fresh. Start with 100 free credits — no credit card.

What is the TikTok Shop Product Details API?

Pass a TikTok Shop product URL and get the PDP as clean JSON. Price is the field this endpoint exists for: promotion_product_price.min_price.sale_price_decimal first, then per-SKU sale prices when the guest min is masked as *, then product_price_info, then the mobile-API actor (native title without a price is not a finished call). priceStatus is extracted | region_restricted | not_extracted — region_restricted means TikTok shipped * / a region-locked shell (try another region); not_extracted means no path returned a number (retrying will not help). currency only when an amount exists. originalPrice + discountPercent + savingsAmount when a seller deduction exists. sold is per-product sold_info.sold_count (or the mobile-API product-level 'stock' when skus[] is empty — that number is units sold, the opposite of inventory). stock is the sum of SKU available_quantity and is omitted when TikTok does not expose variant qty. seller includes id, name, store url, rating, productCount, and logo — id/url come from seller_model and store URLs in the PDP HTML, not only product_model.seller_id. images[] are Shop CDN URLs; t=555f072d is a build token identical across the gallery, not an expiry — mediaUrlsExpireAt is present and null. Accepts www /pdp/{id} and shop.tiktok.com/view/product/{id}?region=BR — the id is the path segment; region / oec_region on the TikTok URL wins over the API default US. An unresolved product is HTTP 404 at 0 credits (never a 200 empty shell with priceStatus=not_extracted). Flat 2 credits when the product exists. relatedVideos[] and seller.tiktokUrl are not in US PDP SSR today.

What you get

  • Flat 2 credits
  • priceStatus extracted|region_restricted|not_extracted
  • sold (units sold) separate from stock (SKU available_quantity)
  • seller{id,name,url,rating,productCount,logo}
  • images[] durable Shop CDN; mediaUrlsExpireAt present and null
  • 404 at 0 credits when the product does not resolve

Try it

Open in Playground

Fill in the parameters below and copy a ready-to-run request, or open the live Playground to run it against your account (no API key paste).

Parameters

Sign in to run live
curl "https://api.captapi.com/v1/tiktok-shop/product-details?url=https%3A%2F%2Fshop.tiktok.com%2Fus%2Fpdp%2Ftrendy-pink-ed-hardy-tough-phone-cases-impact-resistant-wireless-charging-shock-absorption%2F1731098552908944370%3Fsource%3Dproduct_detail%26enter_method%3Durl_semantic_301" \
  -H "Authorization: Bearer capt_live_..."
# or: -H "x-api-key: capt_live_..."

Edit the parameters and the code updates instantly. Switch languages and hit copy.

Example response

{
  "success": true,
  "data": {
    "platform": "tiktok_shop",
    "id": "1731098552908944370",
    "url": "https://shop.tiktok.com/us/pdp/trendy-pink-ed-hardy-tough-phone-cases-impact-resistant-wireless-charging-shock-absorption/1731098552908944370?source=product_detail&enter_method=url_semantic_301",
    "title": "Trendy Pink Ed Hardy Inspired Tough Phone Cases, Phone Durable, Gift, Accessories Top Trendy Phone Cases Phone Cover Hard Case Tough 2-piece Phone Case",
    "description": "Protect your phone in style with this tough phone case. This lightweight phone case is impact resistant and comes with the perfect surface in vivid detail as well as crisp color. Compatible with iPhone X, 11, 12, 13, 14, 15, 16 & more - check our available sizes.\n• 2-piece design with impact resistance and shock dispersion.\n• Materials: polycarbonate (shell), TPU (lining).\n• Interior rubber liner for extra protection (appearance may vary across phone models.\n• Supports wireless charging (not including MagSafe)\n• Lexan plastic: Developed by GE Plastics, this material is extremely strong, durable and impact resistant\n• Lay-flat bezel: Protects the screen from small scratches\n• Flexible rubber liner: Absorbs shock from impacts\n• Glossy Finish: Full color decoration with glossy finish\n• UV protected: Excellent resistance to outdoor weathering, long-term optical quality.\n• Glossy Finish: Full color decoration with glossy finish",
    "price": 22.54,
    "originalPrice": 24.09,
    "currency": "USD",
    "discount": "6%",
    "savings": "Saving $1.55",
    "rating": 4.6,
    "reviews": 48,
    "priceBasis": "pdp-promo-min",
    "priceStatus": "extracted",
    "sold": 5801,
    "stock": 2692,
    "mediaUrlsExpireAt": null,
    "image": "https://p16-oec-general-useast5.ttcdn-us.com/tos-useast5-i-omjb5zjo8w-tx/cc79ccfd6a324d548de31cb761b6c3c4~tplv-fhlh96nyum-crop-webp:794:794.webp?dr=12190&t=555f072d&ps=933b5bde&shp=8dbd94bf&shcp=e1be8f53&idc=useast5&from=2378011839",
    "seller": {
      "id": "7496126292994264050",
      "name": "Timeless Teapot Creations",
      "url": "https://www.tiktok.com/shop/store/timeless-teapot-creations/7496126292994264050",
      "rating": 4.6,
      "productCount": 85,
      "logo": "https://p16-oec-general-useast5.ttcdn-us.com/tos-useast5-i-omjb5zjo8w-tx/587383daaf8a4eaaa4dfb4c8f2b5944f~tplv-fhlh96nyum-resize-png:300:300.png?dr=12184&t=555f072d&ps=933b5bde&shp=905da467&shcp=6ce186a1&idc=useast5&from=2422056039"
    },
    "skus": [
      {
        "id": "1731098558045590514",
        "stock": 84,
        "price": 22.54,
        "originalPrice": null,
        "status": "1",
        "warehouseId": "7495541999400830766",
        "purchaseLimit": null,
        "saleProps": [
          {
            "propName": "Phone Models",
            "propValue": "iPhone 16 E"
          }
        ]
      },
      {
        "id": "1731098558045656050",
        "stock": 51,
        "price": 22.54,
        "originalPrice": null,
        "status": "1",
        "warehouseId": "7495541999400830766",
        "purchaseLimit": null,
        "saleProps": [
          {
            "propName": "Phone Models",
            "propValue": "iPhone 16"
          }
        ]
      }
    ],
    "images": [
      "https://p16-oec-general-useast5.ttcdn-us.com/tos-useast5-i-omjb5zjo8w-tx/cc79ccfd6a324d548de31cb761b6c3c4~tplv-fhlh96nyum-crop-webp:794:794.webp?dr=12190&t=555f072d&ps=933b5bde&shp=8dbd94bf&shcp=e1be8f53&idc=useast5&from=2378011839",
      "https://p16-oec-general-useast5.ttcdn-us.com/tos-useast5-i-omjb5zjo8w-tx/4fe011977a9d4350ba9d7acf0e502f52~tplv-fhlh96nyum-crop-webp:794:794.webp?dr=12190&t=555f072d&ps=933b5bde&shp=8dbd94bf&shcp=e1be8f53&idc=useast5&from=2378011839"
    ],
    "saleProperties": [
      {
        "id": "7494493199692793646",
        "name": "Phone Models",
        "values": [
          {
            "id": "7474656136961246982",
            "name": "iPhone 16 E"
          },
          {
            "id": "7495574204532655878",
            "name": "iPhone 16"
          }
        ]
      }
    ],
    "categories": [
      {
        "id": "601739",
        "name": "Phones & Electronics"
      },
      {
        "id": "909064",
        "name": "Mobile Phone Accessories"
      }
    ],
    "region": "US"
  }
}

Billing metadata is returned in response headers: X-Captapi-Credits (credits charged), X-Captapi-Cache (hit or miss), and X-Captapi-Source. Failed requests (4xx/5xx) are never charged. See the full list of error codes in the error reference.

Response structure

A successful call returns success and a data object with the following fields:

Top-level fields

  • platformAlways tiktok_shop for this endpoint.
  • idStable platform ID for the item.
  • urlCanonical URL of the item.
  • titleTitle of the item.
  • descriptionDescription text.
  • pricePDP promo-min (priceBasis=pdp-promo-min). Source order: sale_price_decimal, then per-SKU sale prices when the guest min is *, then product_price_info, then the mobile-API actor. Always a bit higher than Shop Search's serp-promo-min on the same product; the ratio drifts (~0.7–1.1%). Null with priceStatus=region_restricted means TikTok masked the amount (often a region/session shell) — retry with another region. Null with priceStatus=not_extracted means the product exists but no path returned an amount; retrying will not help. The 2-credit charge still applies because the product resolved. A URL that does not resolve is 404 at 0 credits — there is no priceStatus on that path.
  • originalPriceList / pre-discount price when TikTok exposes a seller deduction or origin price; null when the PDP has no promo. Same pdp-promo-min tier as price.
  • currencyISO currency of the priced amounts. Omitted when price is unknown.
  • discountDiscount amount, percentage, or display string when the platform exposes one.
  • savingsSavings. Example: "Saving $1.55".
  • ratingAverage rating.
  • reviewsNumber of reviews.
  • priceBasis"pdp-promo-min" — the full-PDP promo tier. Distinct from Shop Search's serp-promo-min. Both are legitimate; they are not the same number.
  • priceStatusextracted when price is a number. region_restricted when TikTok shipped * / a region-locked guest shell (try region=US or the product's market). not_extracted when the product exists but no path returned an amount — retrying the same region will not help. Absent on 404 (the product did not resolve).
  • soldPer-product units sold from sold_info.sold_count (never the shop header). The mobile-API actor names this field stock — when skus[] is empty we remap that number here. High sold is demand, not inventory.
  • stockSum of available_quantity across skus[] (use skus[].stock for per-variant inventory). Omitted when TikTok does not expose SKU quantities — not null. A lone product-level 'stock' with empty skus[] is sold, not this field (TSP-2).
  • sourcenative when SSR produced the price; extended when a follow-on fill supplied the price.
  • mediaUrlsExpireAtAlways keyed. Null here — Shop image t= tokens are build ids, not CDN expiry. Contrast TikTok video CDN, where this is a real timestamp.
  • imageImage URL.
  • imagesProduct gallery image URLs from the PDP (not a single OG thumbnail). t=555f072d is a build/version token identical across the gallery — not a timestamp and not a per-URL signature. These Shop CDN links are durable; mediaUrlsExpireAt is present and null so the key matches popular-songs. Persist the URLs. TikTok video CDN is the surface that expires.
  • regionMarket used for the lookup. A region= / oec_region= query on the product URL wins over the API region parameter (default US). Not a creator country and not AI-inferred.

Seller

The seller object contains:

  • idId of this seller item.
  • nameName of this seller item.
  • urlCanonical URL of the item.
  • ratingAverage rating.
  • productCountProduct count. Example: 85.
  • logoLogo image URL.

Skus

Each item in skus contains:

  • idId of this skus item.
  • stockSum of available_quantity across skus[] (use skus[].stock for per-variant inventory). Omitted when TikTok does not expose SKU quantities — not null. A lone product-level 'stock' with empty skus[] is sold, not this field (TSP-2).
  • pricePDP promo-min (priceBasis=pdp-promo-min). Source order: sale_price_decimal, then per-SKU sale prices when the guest min is *, then product_price_info, then the mobile-API actor. Always a bit higher than Shop Search's serp-promo-min on the same product; the ratio drifts (~0.7–1.1%). Null with priceStatus=region_restricted means TikTok masked the amount (often a region/session shell) — retry with another region. Null with priceStatus=not_extracted means the product exists but no path returned an amount; retrying will not help. The 2-credit charge still applies because the product resolved. A URL that does not resolve is 404 at 0 credits — there is no priceStatus on that path.
  • originalPriceList / pre-discount price when TikTok exposes a seller deduction or origin price; null when the PDP has no promo. Same pdp-promo-min tier as price.
  • statusStatus value for this endpoint (see the field note on this page for enum meaning).
  • warehouseIdWarehouse id. Example: "7495541999400830766".
  • purchaseLimitPurchase limit.
  • salePropsArray of objects with propName, propValue.

Sale properties

Each item in saleProperties contains:

  • idId of this sale properties item.
  • nameName of this sale properties item.
  • valuesArray of objects with id, name.

Categories

Each item in categories contains:

  • idId of this categories item.
  • nameName of this categories item.

Parameters

NameTypeRequiredDescription
urlstringYesTikTok Shop product URL, e.g. https://shop.tiktok.com/view/product/1731410956394792439?region=BR or https://www.tiktok.com/shop/pdp/1731098552908944370. The URL platform must match this endpoint's platform. Do not pass cross-platform URLs, e.g. YouTube to TikTok, Instagram to Facebook, LinkedIn to X/Twitter, or Pinterest to Rumble.
regionstringNoTwo-letter market region (default US). A region= or oec_region= query on the product URL wins over this default so a BR share URL is not fetched as US. Echoed as data.region.
cachebooleanNoSet true to serve from the 24h response cache (0 credits on hit). Default false — always fetch fresh.

Authentication: send your key as Authorization: Bearer capt_live_.... A typical call costs 2 credits. Pass cache=true for a free 24h cache hit; default is always fresh.

Using an AI agent? This endpoint is the MCP tool tiktok_shop_product_details via @captapi/mcp. Set it up →

How it works

  1. 1. Sign up — get 100 free credits, no card required.
  2. 2. Create a key from your dashboard.
  3. 3. Send one request to /v1/tiktok-shop/product-details and parse the JSON response.

Use cases

Variant Stock Tracking

Watch skus[].stock + saleProps so you know which Color/Size is actually depleting.

Price & Promo Truth

Read price/originalPrice/discountPercent/savingsAmount on the PDP (priceBasis=pdp-promo-min). That is a different promo tier than Shop Search's serp-promo-min — do not expect the numbers to match.

Assortment & Categories

Use categories[] and saleProperties[] to classify SKUs without scraping the storefront UI.

Seller Join

Take seller.id / seller.url into Shop Products for the full store catalog.

Frequently asked questions

What does the TikTok Shop Product Details API do?+

The TikTok Shop Product Details API lets you fetch full metadata and key stats from a public TikTok Shop listing or product using one GET request to /v1/tiktok-shop/product-details. It returns clean JSON — no OAuth or infrastructure setup required.

How many credits does the TikTok Shop Product Details API cost?+

Each successful call costs 2 credits. Pass cache=true to serve from the 24h cache (0 credits on hit); default is always fresh. Selected profile endpoints also accept cacheMaxAge=1d|3d|7d|14d|30d. Failed or empty results are never charged.

Do I need a TikTok Shop API key or OAuth?+

No. A single Captapi key works across every platform Captapi supports — YouTube, TikTok, Instagram, Facebook, Twitter/X, Reddit, Threads, Bluesky, Pinterest, LinkedIn, Rumble, Spotify, Kwai, and more. We handle proxies, rate limits, retries, and authentication for you.

Why was price null next to a title and nine images?+

Read priceStatus. region_restricted means TikTok shipped * / a region-locked guest shell — retry with the product's market (often BR) or region=US. not_extracted means no path returned a number on a product that exists; retrying the same region will not help. We take sku_min / product_price_info, try shop.tiktok.com/view/product/{id}?region= first, then fill from the mobile-API actor (20s wait) — and when the first PDP pass was rate-limited and the actor came back priceless, the PDP is fetched once more in the same request (the actor's ~20s is a natural backoff), so a transient 429 wave does not ship a priceless shell. The call stays 2 credits because the product resolved and the PDP fetch ran. A URL that does not resolve is 404 at 0 credits — not a 200 with priceStatus=not_extracted.

What if the product URL does not resolve?+

HTTP 404, 0 credits. We parse the path segment after /pdp/ or /view/product/ and read region from the URL query (region / oec_region). An empty 200 with every field null was a parse miss wearing an extraction miss — that is gone. priceStatus=not_extracted is only for a real PDP whose price no path could read.

Is stock inventory or units sold?+

stock is SKU available_quantity (summed on the product; per-variant on skus[].stock). sold is sold_info.sold_count. The mobile-API actor names units sold "stock" — when skus[] is empty we remap that number to sold so 94 839 of one t-shirt is not read as warehouse qty. High sold is demand; high stock is supply.

Why is seller only a name?+

id and url come from seller_model.seller_id / shop_id, not only product_model.seller_id. url is https://www.tiktok.com/shop/store/{slug}/{id} — chain it into /tiktok-shop/products. rating / productCount / logo fill when the shop card is on the PDP.

Do image URLs expire?+

Shop gallery URLs carry t=555f072d — a build token identical across the set, not a CDN expiry. mediaUrlsExpireAt is present and null; persist the image URLs. TikTok video CDN is the surface that dies. source is native | extended.

Is the TikTok Shop Product Details API suitable for production use?+

Yes. It is a stable REST endpoint with predictable JSON and automatic retries. Pass cache=true to serve from the 24h cache (0 credits on hit); default is always fresh. Selected profile endpoints also accept cacheMaxAge=1d|3d|7d|14d|30d. Use it for analytics, monitoring, and content automation.

More TikTok Shop APIs

Ready to use the TikTok Shop Product Details API?

Sign up, grab your key, and make your first call in 60 seconds.

TikTok Shop Product Details API | Captapi — Captapi