Cusp: Google Trends Spike & Trend Detector (Any Dataset)
Pricing
from $3.00 / 1,000 series analyzeds
Cusp: Google Trends Spike & Trend Detector (Any Dataset)
Find which Google Trends keywords are really taking off, which prices just dropped, and which scrapers silently broke. Point Cusp at any dataset with a date and a number; every finding is computed from your data with the evidence attached. No AI.
Pricing
from $3.00 / 1,000 series analyzeds
Rating
0.0
(0)
Developer
Аида Абасилова
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Cusp — Google Trends Spike & Trend Detector (works on any scraper dataset)
Run Google Trends Scraper. Cusp tells you which keywords are really taking off — in plain English, with the numbers to prove it.
It works the same on any dataset with a date and a number: competitor prices, review counts, rankings, followers. And it warns you when a scraper silently starts returning empty data.
Try it in 10 seconds
Open the Input tab and run with the example data already filled in — 24 weeks of search interest for one keyword. Cusp returns:
Interest settled at a new level around 41 (+78% from about 23), holding for 8 weeks since 2026-06-21. 44 on 2026-08-09 is also the highest of all 24 readings.
Other real outputs, on sample data:
Price fell 19% below the 13-day median (15,990 → 12,990) on 2026-09-14. 12,990 is also the lowest of all 14 readings.
The last 14 days are exactly 0, after a typical level of 6. The data source may have stopped reporting — check the scraper, tracking or integration.
Every observation is calculated from your numbers and written from a fixed template — no language model is involved, so Cusp cannot report a trend that is not in the data. The statistics behind each finding are attached so you can check them.
Cusp vs. the alternatives
| Cusp | Eyeballing a chart / a spreadsheet | Asking a chatbot | |
|---|---|---|---|
| 100 keywords or products at once | ✅ one run | ❌ one by one | ⚠️ long tables get misread |
| Same answer every time | ✅ | ⚠️ depends who looks | ❌ varies run to run |
| Ignores normal noise and weekly cycles | ✅ calibrated: ≤ 5% false alarms on 60-point series of pure noise | ❌ | ❌ |
| Runs on a schedule after your scraper | ✅ Integrations + history | ❌ | ❌ |
| Shows the evidence (baseline, z-score, p-value) | ✅ | — | ❌ |
What does Cusp find?
| Type | What it means | Example |
|---|---|---|
spike | A value far above its recent normal level | Sessions rose 225% above the 14-day median (123 → 400) on 2026-09-14. |
drop | A value far below its recent normal level | Price fell 19% below the 13-day median (15,990 → 12,990). |
sustained_trend | A run of consecutive rises/falls, or a statistically significant trend (Mann–Kendall) | Interest shows a statistically significant upward trend over the last 30 weeks: about +1.15 per week, +70% relative to its median of 47.5 (Mann–Kendall p < 0.001). |
level_shift | A step change to a new plateau that holds — a "new normal", not a one-day blip | Sessions settled at a new level around 600 (−50% from about 1,203), holding for 7 days. |
record | A new all-time high or low | Price reached 12,990 — the lowest of all 14 readings. |
reversal | A streak of gains (or losses) that just turned around | Value fell 16% to 27, after 6 consecutive gains. |
data_stopped | The series ends in zeros or missing values — usually a broken scraper, tag or integration | The last 3 days have no numeric value, after 11 readings that did. |
Cusp is deliberately conservative. It compares weekdays with the same weekday (a normal Saturday dip is not a "drop"), uses Poisson tests for low-volume counts (4 reviews instead of the usual 1 is not a "spike"), leaves out unfinished periods, and with too few points it reports nothing rather than guessing.
Because the output is verified facts, Cusp is also a good tool for AI agents: the agent calls Cusp and writes its answer from computed numbers (see Use from AI agents (MCP)).
How to use it
- Run any scraper (Google Trends, Amazon, Kaspi, Google Maps reviews, Instagram followers…).
- Open Cusp, pick the scraper's dataset, and tell it which field holds the date and which holds the number. Use One series per… when the dataset covers many products, places or keywords.
- Run. You get a dataset of observations (one row each) and a Markdown REPORT in the key-value store.
Cusp never scrapes anything itself, so it doesn't break when websites change.
Recipes
Google Trends spike & trend detector
Run Google Trends Scraper, then:
{"datasets": ["<Google Trends Scraper dataset>"],"unwindField": "interestOverTime_timelineData","dateField": "time","valueField": "value.0","groupBy": "searchTerm","valueLabel": "Interest"}
The unfinished current week (isPartial) is skipped automatically, so it's never mistaken for a drop.
Price drop alerts & price change monitoring
Most price scrapers (Amazon, Kaspi.kz, Shopify, eBay…) output one snapshot per run without a date. Pick the datasets of several runs and use each dataset's creation time as the date:
{"datasets": ["<run 1>", "<run 2>", "<run 3>", "…"],"dateSource": "datasetCreatedAt","valueField": "price","groupBy": "title","interval": "day","valueLabel": "Price"}
Prices like "1,299.00", "$4.50" or "12 990 ₸" are read correctly. A value that is missing or not a number is treated as missing, never as 0. When the price goes missing for several runs in a row, you get a data_stopped alert: the scraper probably broke.
Monitoring on autopilot: schedule your scraper, open its Integrations tab and add Cusp to run when a run succeeds, with this input:
{"datasetId": "{{resource.defaultDatasetId}}","dateSource": "datasetCreatedAt","valueField": "price","groupBy": "title","historyKey": "my-prices"}
Cusp keeps the history in your account, adds only points newer than the ones it already stored, and analyzes the whole history on every run. Filter the dataset by severity or record to catch "lowest price ever".
Review velocity monitor (Google Maps, Trustpilot, app stores)
Turn a list of reviews into reviews per week per place, and find sudden surges (a viral post, or fake reviews) or silence:
{"datasets": ["<reviews dataset>"],"dateField": "publishedAtDate","groupBy": "title","aggregation": "count","interval": "week","endDate": "2026-09-28","valueLabel": "Reviews"}
endDate is the date the data was collected. Weeks with no reviews up to that date count as 0, and the week still in progress is left out.
Broken scraper detector
Run Cusp on your scraper's output with historyKey on a schedule. When a field starts coming back empty or a count drops to zero, you get a data_stopped observation with high severity, often days before someone notices by hand.
Any metric over time
Followers, rankings, stock levels, API usage, sales. Anything with a date and a number works. You can also paste the numbers directly:
{ "data": [{ "date": "2026-09-01", "value": 120 }, { "date": "2026-09-02", "value": 118 }] }
or even { "data": [120, 118, 125, 410] } (analyzed in order).
Input
| Field | What it does | Default |
|---|---|---|
datasets | Datasets to read (several = one combined table) | — |
datasetId | One dataset, for integrations: {{resource.defaultDatasetId}} | — |
data | Inline data for trying Cusp: objects, [date, value] pairs or plain numbers. Ignored when a dataset is given | example |
dateField | Field with the date/time (ISO, Unix seconds or ms). Dots for nested fields | date |
valueField | Field with the number. value.0 addresses array items | value |
groupBy | Separate series per distinct value of this field | one series |
unwindField | A list field whose elements become rows (e.g. Google Trends timeline) | — |
dateSource | field, datasetCreatedAt (one run = one point) or order | field |
interval | Bucket rows by hour, day, week (Monday start), month, or none | none |
aggregation | Combine rows in a bucket: last, first, sum, mean, min, max, count | last |
endDate | For sum/count: when the data was collected, to count quiet periods as 0 | — |
historyKey | Remember points between runs under this name (monitoring) | — |
sensitivity | low, medium, high | medium |
minSeverity | low = everything; medium or high for alerts | low |
baselineWindow | Points in the rolling baseline | 14 |
shiftWindow | Points that must hold a new level to call it a "new normal" | 5 |
recentPoints | Look for spikes, drops and records in the last N points (0 = all) | 7 |
trendWindow | Points used by the trend test | 30 |
minPoints | Fewer usable points → not analyzed (and not charged) | 8 |
includeQuietSeries | Add a no_change / insufficient_data row for such series | true |
skipPartialRows | Skip rows a scraper marks as unfinished (e.g. Google Trends isPartial) | true |
valueLabel | Word used in the sentences ("Price", "Interest") | from valueField |
maxSeries | Stop after this many series | 5,000 |
maxItems | Stop reading after this many rows (500,000 max at the default 256 MB) | 200,000 |
If a field name is wrong, the run stops with a message listing the fields that do exist in your data.
Output
One dataset row per observation:
{"seriesKey": "iPhone 15 128GB","type": "drop","direction": "down","severity": "medium","startDate": "2026-09-27","endDate": "2026-09-27","value": 12990,"baseline": 15990,"changePercent": -18.8,"record": "low","explanation": "Price fell 19% below the 13-day median (15,990 → 12,990) on 2026-09-27. 12,990 on 2026-09-27 is also the lowest of all 14 readings (previous low 15,990 on 2026-09-14).","evidence": {"method": "rolling_median_robust_z","zScore": -31.12,"baselineWasFlat": false,"baselineMedian": 15990,"baselineSpread": 96.4076923077,"baselineWindow": 13,"sameSeasonMedian": 15990,"threshold": "stable","consecutivePoints": 1,"peakDate": "2026-09-27","previousRecord": 15990,"previousRecordDate": "2026-09-14"}}
severity:high,mediumorlow, so you can filter to what matters.record:high/lowwhen the value is also an all-time extreme, whatever thetype.evidence: the statistics behind the finding (z-score, baseline, p-value, run length…).
The key-value store also gets REPORT, a readable Markdown summary with the most important series first, and SUMMARY, JSON with per-series stats.
Use from AI agents (MCP)
Cusp works as a tool in Claude, Cursor, VS Code and any other MCP client through the Apify MCP server:
https://mcp.apify.com?tools=AidaAbassilova/cusp
Add it next to your scraper tools, e.g. ?tools=apify/google-trends-scraper,AidaAbassilova/cusp, and ask: "Get Google Trends for these 5 keywords and tell me which ones are really taking off." The agent fetches the data, calls Cusp, and answers from computed facts instead of eyeballing a table.
For agents, the simplest call passes numbers inline: {"data": [{"date": "2026-09-01", "value": 12}, …]}.
Pricing
$0.003 per series analyzed. A series is one keyword, one product or one place. Nothing else is billed per row or per finding.
| What you check | One run | Daily for a month |
|---|---|---|
| 5 Google Trends keywords | $0.015 | about $0.45 |
| 100 products | $0.30 | about $9 |
| 1,000 products | $3 | about $90 |
- Every analyzed series is billed once per run, whether or not it has findings — no findings is also an answer.
- Series with too little data (fewer than
minPoints) are not analyzed and cost nothing. - If the run is restarted by the platform, series already finished are not billed again.
- Cusp needs 256 MB and runs in seconds, so platform usage stays small. You can cap a run's cost with the maximum charge setting.
How it works
- Spikes and drops: each recent point is compared with the median of the previous
baselineWindowpoints using a robust z-score (median absolute deviation). It must also clear a minimum relative change, a larger one for volatile series and a smaller one for very stable ones like prices, and it must also be unusual compared with the same weekday (daily data) or hour (hourly data). Low-volume counts must also pass a Poisson test. - Trends: a run of at least 5 consecutive moves in one direction (medium sensitivity), or a Mann–Kendall test with a Theil–Sen slope over the last
trendWindowpoints. Both need a move that is large next to the series' noise before they rate above low. - Calibration (synthetic daily series, checked in the test suite on every change):
- pure noise — Poisson counts, ±10% and ±30% noise, weekly cycles: a medium or high finding in at most 5% of 60-point series and at most 7% of 14–30-point series. Shorter history means less certainty, so give Cusp at least a month of data for monitoring;
- a step is reported as a level shift reliably (≥ 95%) when it is about 3× the day-to-day noise or more — e.g. −20% on ±3% noise, −30% on ±5%, −50% on ±10%. A +40% step on ±10% noise is a level shift in ~80% of cases and still a medium/high finding in ≥ 95%. Smaller steps on noisier data may show up only as a drop or a trend.
- Level shifts: Cusp tries every split of the recent stretch into an "old level" and a "new level" and keeps the split that two medians describe best. It reports a shift only if the jump is well beyond the noise on both sides, the new level held for at least
shiftWindowpoints, both levels are flat, and two levels fit clearly better than one straight line (a ramp is a trend, not a step). The overlapping spike/drop/trend is folded in so the same event is reported once. From a zero baseline (a new product, a page that just started getting reviews) there is no percentage to compare, so Cusp asks instead whether the old rate could have produced that much (Poisson) and reports a new level of at least 3. - Records: a strict new all-time high or low within the recent points. Ties don't count, and a record only gets medium/high severity if it beats the old one by more than the series' usual wobble.
- Reversals: a run of at least 5 moves that the latest one or two moves turned against by at least 10%.
- Data stopped: trailing missing values or zeros after a clearly non-zero history. For counts, the number of zeros needed depends on volume (Poisson).
FAQ
Does Cusp scrape websites? No. It only analyzes data you already have, so it doesn't break when sites change and needs no proxies.
Is my data sent to an AI model? No. Everything is computed inside the run.
Can it forecast? No, on purpose. Cusp reports what the data shows, not predictions.
What if my dates are in another format? ISO dates, date-times and Unix timestamps work out of the box. If your dataset has no dates, use dateSource: "datasetCreatedAt" (one run = one point) or "order".
Found a bug or need a new recipe? Open an issue in the Issues tab. Real-world datasets that trip Cusp up are the most useful reports.