On 2026-08-07, TikTok Shop listed "LIOUOU Portable Coffee Maker" at rank 3 on the Hot Products board (as_of 2026-08-07T08:01:34Z). The keyword "portable coffee maker" on Trends API showed Amazon score 73.5 with 50,026 recent volume (+18.36% over 30D, +27.83% over 3M), YouTube score 72.0 (+9.09% over 30D, -28.0% over 3M), Google Search score 2.0 (flat over 14D, -97.44% over 3M), and Google Shopping score 3.0 (+200.0% over 14D, -94.23% over 3M). TikTok time series for the plain keyword returned no_data. This post builds a Python product-research script against POST https://api.trendsapi.ai/api and double-parses the body string. For the evergreen pytrends comparison, see pytrends alternative.

Why a Shop rank is not enough

A TikTok Shop rank is a discovery signal. Buying and search demand can diverge. Trends API exposes that divergence as separate source values under one Bearer token. Amazon source docs live at Amazon Trends. Google Search docs live at Google Trends.

Capacity planning: free tier 100 successful requests per month, Starter 5,000, Pro 25,000, Business 100,000. Only HTTP 200 responses count.

Step 1: shared client with double body parse

import json
import os
import urllib.request

API = "https://api.trendsapi.ai/api"
KEY = os.environ["TRENDSAPI_API_KEY"]

def trends_api(payload: dict) -> dict:
    req = urllib.request.Request(
        API,
        data=json.dumps(payload).encode(),
        headers={
            "Authorization": f"Bearer {KEY}",
            "Content-Type": "application/json",
        },
        method="POST",
    )
    envelope = json.loads(urllib.request.urlopen(req).read().decode())
    # body is a JSON string; parse it again
    return json.loads(envelope["body"])

Every successful envelope looks like {"statusCode": 200, "body": "..."}. Skipping the second parse is the usual failure mode in new clients.

Step 2: pull the live Shop board for candidates

board = trends_api({
    "mode": "get_top_trends",
    "type": "TikTok Shop Hot Products",
    "limit": 15,
})
for rank, name in board["data"]:
    print(rank, name[:80])

Live top five on 2026-08-07:

Rank Product (truncated)
1 Buenoble Silky Lace Trim Shorts for Women
2 Wig Storage Bag, 5pcs/set Zipper Transparent Dustproof Design
3 LIOUOU Portable Coffee Maker Self-Heating Espresso Machine
4 ARMAF Odyssey Nexus Aqva Edition Eau de Parfum
5 Hydration Sticks 2 Pack and 3 Pack Bundles

The board returned count 15 with offset 0. Rank 3 becomes the research keyword after stripping brand noise to "portable coffee maker".

Step 3: Amazon growth with absolute volume

amazon = trends_api({
    "mode": "get_growth",
    "source": "amazon",
    "keyword": "portable coffee maker",
    "percent_growth": ["14D", "30D", "3M"],
})
for row in amazon["results"]:
    print(row)

Live Amazon results from 2026-08-07:

Period Status Recent date Recent value Baseline value Growth Recent volume Volume growth
14D error (collapsed_range) n/a n/a n/a n/a n/a n/a
30D success 2026-07-31 73.5 62.1 18.36% 50,026 18.25%
3M success 2026-07-31 73.5 57.5 27.83% 50,026 27.74%

Baseline volumes were 42,305 (30D) and 39,162 (3M). Metadata reported 49 underlying points and all_successful: false because the 14D preset collapsed. Keep that error in the research log instead of inventing a short-window percent.

Step 4: Google Search and Google Shopping side by side

gsearch = trends_api({
    "mode": "get_growth",
    "source": "google search",
    "keyword": "portable coffee maker",
    "percent_growth": ["14D", "30D", "3M", "12M"],
})
gshop = trends_api({
    "mode": "get_growth",
    "source": "google shopping",
    "keyword": "portable coffee maker",
    "percent_growth": ["14D", "30D", "3M"],
})

Live Google Search rows:

Period Recent date Recent value Baseline value Growth Direction
14D 2026-08-01 2.0 2.0 0.0% flat
30D 2026-08-01 2.0 3.0 -33.33% decrease
3M 2026-08-01 2.0 78.0 -97.44% decrease
12M 2026-08-01 2.0 1.0 100.0% increase

Live Google Shopping rows (261 points, all three windows completed):

Period Recent date Recent value Baseline value Growth Direction
14D 2026-08-01 3.0 1.0 200.0% increase
30D 2026-08-01 3.0 0.0 999999.0% increase
3M 2026-08-01 3.0 52.0 -94.23% decrease

The 30D Shopping window starts from a 0.0 baseline. Report the raw API growth and treat it as a sparse-window warning, not a planning input. The useful read is recent score 3.0 after a 3M collapse from 52.0, while Amazon commerce stays elevated near 73.5.

Step 5: YouTube for creative demand

youtube = trends_api({
    "mode": "get_growth",
    "source": "youtube",
    "keyword": "portable coffee maker",
    "percent_growth": ["30D", "3M", "12M"],
})
for row in youtube["results"]:
    print(row["period"], row["recent_value"], row["growth"], row["direction"])

YouTube returned score-only rows with 261 data points and three successful calculations:

Period Recent date Recent value Baseline date Baseline value Growth
30D 2026-08-01 72.0 2026-07-04 66.0 9.09%
3M 2026-08-01 72.0 2026-05-02 100.0 -28.0%
12M 2026-08-01 72.0 2025-08-02 46.0 56.52%

Video interest is high on a 12M basis and off the 3M peak. That pattern pairs with Amazon volume growth: creative still has fuel, but the 3M YouTube baseline of 100.0 says the category already had a larger wave earlier in 2026.

Step 6: record TikTok absence instead of inventing it

tiktok = trends_api({
    "mode": "get_growth",
    "source": "tiktok",
    "keyword": "portable coffee maker",
    "percent_growth": ["7D", "14D", "30D"],
})
print(tiktok)

This call returned HTTP-level no_data for the keyword and source. The Shop board ranks a branded SKU; the plain keyword has no TikTok hashtag series in Trends API today. Absence is a finding. Do not backfill with board rank as if it were a 0-100 score.

Optional second pass: hydration sticks as a control keyword

Rank 5 on the same Shop board was "Hydration Sticks". A quick Amazon control call helps decide whether portable coffee makers are an outlier or part of a broader commerce lift.

hydration = trends_api({
    "mode": "get_growth",
    "source": "amazon",
    "keyword": "hydration sticks",
    "percent_growth": ["30D", "3M", "12M"],
})

Live Amazon control rows from 2026-08-07 (46 points, all three windows successful):

Period Recent date Recent value Baseline value Growth Recent volume Volume growth
30D 2026-07-31 16.1 17.3 -6.94% 13,332 -6.83%
3M 2026-07-31 16.1 12.7 26.77% 13,332 26.84%
12M 2026-07-31 16.1 30.9 -47.9% 13,332 -47.92%

Baseline volumes were 14,309 (30D), 10,511 (3M), and 25,601 (12M). Hydration sticks also rose over 3M, but the absolute Amazon score (16.1) and volume (13,332) sit far below portable coffee maker (73.5 / 50,026). The coffee keyword is the stronger commerce candidate on this board sample.

Research verdict for this SKU cluster

Signal Reading on 2026-08-07
TikTok Shop board Rank 3 branded unit on Hot Products
Amazon Score 73.5, volume 50,026, +27.83% over 3M
YouTube Score 72.0, +56.52% over 12M, -28.0% over 3M
Google Search Score 2.0, -97.44% over 3M
Google Shopping Score 3.0, -94.23% over 3M
TikTok keyword series no_data
Control Amazon keyword hydration sticks score 16.1, volume 13,332

Commerce and video stay strong while web search and shopping interest sit near the floor. A Google-only pytrends pull would have missed the Amazon and YouTube strength. Put the script on a daily cron, store each source row with data_date, and alert when Amazon volume growth stays positive while Google Search remains under 5.0 for two consecutive pulls. For the library replacement framing, read pytrends alternative. For another multi-source brand pattern, see Nike multi-source brand signals in Python.