A demand sensing pipeline watches a product keyword list on a schedule, scores each term across Amazon, Google Shopping, Google Search, and YouTube, then writes volume and growth into an alert table. On the 2026-08-11 pull, TikTok Shop Hot Products ranked a facial hydrocolloid acne patches SKU at #4 (as_of_ts 2026-08-10T00:01:32Z). The category term acne patches on Amazon sat at score 47.9 with volume 190,441 on 2026-07-31 (+5.97% over 30D, -1.03% over 3M, -10.13% over 12M). Google Shopping sat at 5.0 on 2026-08-08 (+150.0% over 7D from 2.0 on 2026-08-01, -89.13% over 3M). Google Search sat at 41.0 on 2026-08-08 (0.0% over 7D, -48.1% over 3M). YouTube sat at 60.0 on 2026-08-08 (+53.85% over 7D, +39.53% over 3M). One Bearer POST powers boards, growth, and time series.
What the job needs from Trends API
Demand sensing is not a dashboard product. It is a cron loop with three API modes. get_top_trends discovers what shoppers are buying now. get_growth scores a fixed watchlist for short and long windows. get_time_series supplies dated points when an alert needs a chart or a threshold against history. The Python Trends API client pattern is enough to ship the first job. For a related SKU-to-scorecard walkthrough, see acne patches product signals.
import json
import os
import requests
API_URL = "https://api.trendsapi.ai/api"
API_KEY = os.environ["TRENDSAPI_API_KEY"]
def trends_api(payload):
res = requests.post(
API_URL,
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json=payload,
timeout=60,
)
res.raise_for_status()
envelope = res.json()
# body is a JSON string; parse it a second time
return json.loads(envelope["body"])
Free tier is 100 successful requests per month. Starter 5,000. Pro 25,000. Business 100,000. Only HTTP 200 counts.
Stage 1: discovery boards and a fixed watchlist
Keep two inputs. Input A is a fixed watchlist of category keywords the business already sells or wants to enter. Input B is a live board that can add candidates. For social commerce, use TikTok Shop Hot Products. For marketplace context, use Amazon Best Sellers Top Rated.
WATCHLIST = ["acne patches", "derma roller", "collagen peptides"]
tiktok_shop = trends_api({
"mode": "get_top_trends",
"type": "TikTok Shop Hot Products",
"limit": 15,
})
amazon_board = trends_api({
"mode": "get_top_trends",
"type": "Amazon Best Sellers Top Rated",
"limit": 10,
})
On the 2026-08-11 pull, TikTok Shop limit 15 returned a 140 microneedle derma roller at rank 1, a basic casual round neck short-sleeve sports top at rank 2, GeeYea women's nude ankle strap block heel sandals at rank 3, and facial hydrocolloid acne patches at rank 4. Amazon Best Sellers Top Rated (as_of_ts 2026-08-10T04:01:35Z) led with Amazon Basics 20-pack AA batteries at rank 1, AAA batteries at rank 2, and Crocs Classic Clog at rank 3. Board titles are long SKU strings. Normalize them to short keywords before growth calls, and keep the original rank plus as_of_ts for audit.
Stage 2: multi-source growth scorecard
Call sources one at a time. Comma-separated multi-source growth can time out. Prefer 30D, 3M, 6M, and 12M on Amazon. Keep daily presets for Google Shopping, Google Search, and YouTube. Source docs for Amazon live at Amazon trends.
SOURCES = ["amazon", "google shopping", "google search", "youtube"]
PERIODS = {
"amazon": ["30D", "3M", "6M", "12M"],
"google shopping": ["7D", "14D", "30D", "3M", "12M"],
"google search": ["7D", "14D", "30D", "3M", "12M"],
"youtube": ["7D", "30D", "3M", "12M"],
}
def score_keyword(keyword):
rows = []
for source in SOURCES:
body = trends_api({
"mode": "get_growth",
"source": source,
"keyword": keyword,
"percent_growth": PERIODS[source],
})
for result in body.get("results", []):
rows.append({"source": source, **result})
return rows
Live scorecard: acne patches (2026-08-11)
| Source | Recent date | Score | Volume | 7D | 30D | 3M | 12M |
|---|---|---|---|---|---|---|---|
| amazon | 2026-07-31 | 47.9 | 190,441 | collapsed_range | +5.97% | -1.03% | -10.13% |
| google shopping | 2026-08-08 | 5.0 | n/a | +150.0% | -16.67% | -89.13% | -88.1% |
| google search | 2026-08-08 | 41.0 | n/a | 0.0% | -28.07% | -48.1% | -16.33% |
| youtube | 2026-08-08 | 60.0 | n/a | +53.85% | 0.0% | +39.53% | -13.04% |
Amazon 7D and 14D returned collapsed_range because recent and baseline resolved to the same monthly point. Amazon baselines for the successful periods were 45.2 / 179,342 on 2026-06-30 (30D), 48.4 / 192,363 on 2026-04-30 (3M), 51.5 / 204,575 on 2026-01-31 (6M), and 53.3 / 211,778 on 2025-07-31 (12M). Volume growth matched score growth within 0.3 points on each successful Amazon period.
Google Shopping 14D moved from baseline 0.0 on 2026-07-25 to 5.0 on 2026-08-08. Report those two scores instead of the inflated percent growth. Shopping 6M was -61.54% (5.0 vs 13.0 on 2026-02-07). Search 14D was -16.33% (41.0 vs 49.0 on 2026-07-25). YouTube 14D was -11.76% (60.0 vs 68.0 on 2026-07-25) and 6M was -29.41% (60.0 vs 85.0 on 2026-02-07). A TikTok keyword series for acne patches returned no_data even though TikTok Shop ranked a related acne patches SKU at #4. Keep the board rank and skip inventing a TikTok time series.
Stage 3: time series for alerts and seasonality
Growth answers "up or down versus a baseline." Time series answers "where does today's score sit in history." For Amazon, monthly points back to 2022 are available for acne patches. Peak score was 100.0 with volume 397,188 on 2023-11-30. Later peaks include 95.2 / 378,264 on 2023-10-31, 86.5 / 343,677 on 2024-03-31, and 74.6 / 296,151 on 2024-12-31. The 2026-07-31 tip of 47.9 / 190,441 sits well below those peaks, so a short 30D rebound should not clear a peak-based alert alone.
series = trends_api({
"mode": "get_time_series",
"source": "amazon",
"keyword": "acne patches",
})
peak = max(series, key=lambda p: p["value"])
tip = series[-1]
alert = tip["value"] >= peak["value"] * 0.8
Store tip["date"], tip["value"], tip["volume"], peak["date"], and peak["value"] beside the growth rows. That gives ops both momentum and level.
Stage 4: alert rules that survive bad presets
Write rules that tolerate source quirks. Example rules for a nightly job:
- Amazon 30D growth above +5% and Amazon tip score above 45.0: watchlist flag.
- Google Shopping 7D growth above +100% while Shopping tip score is below 10.0: treat as a low-base spike, require Search confirmation.
- YouTube 7D growth above +50% with Search 7D flat or up: content interest rising before purchase intent.
- Any
collapsed_rangeorno_datarow: keep the status string, do not coerce to 0.
On the 2026-08-11 acne patches pull, rule 1 fires (Amazon +5.97% 30D, tip 47.9). Rule 2 fires as a caution (Shopping +150.0% 7D from 2.0 to 5.0) because Search 7D is 0.0% at 41.0. Rule 3 fires (YouTube +53.85% 7D to 60.0) while Search is flat. That combination is a content-led bounce, not a confirmed purchase spike. Pair this page with the narrower acne patches scorecard when the job needs a full Python walkthrough, or with the ecommerce product research pipeline when the starting point is a shop board rather than a fixed watchlist.
Request budget for a nightly run
A watchlist of 10 keywords across 4 sources is 40 get_growth calls. Add 2 board calls and 10 Amazon get_time_series calls for tips and peaks, and the night costs about 52 successful requests. Free tier (100/month) covers roughly one full run. Starter (5,000) covers daily runs with headroom. Cache board as_of_ts values and skip re-scoring a keyword when every source tip date is unchanged since the last run.