Skip to main content
Glama

Search advertised products

search_products
Read-only

Search e-commerce PRODUCTS that ads lead to — the data behind the website's /shops/products page. One row = ONE product page (domain/products/handle) of ONE shop, with that product's OWN ad counters: ads = ads leading to this product among the ads Spytrend first saw in the last 180 days; ads_active = how many of them were ACTIVE on active_as_of — the day of the daily data snapshot the counters are taken on, returned with the result (say 'active on 04.10', never 'active now'); creatives, reuploads and geos; days_in_ads = days from the product's first launch to today (if something is active) or to its last launch; fb_launch_date / last_launch_date = first and last Facebook launch of the product's ads (YYYY-MM-DD); win_badge = testing (active, under 14 days in ads) | heating (active, 14-29 days) | proven (active, 30+ days and 10+ ads) | ran30 (30+ days, not proven); no badge = not active and under 30 days. price/currency come from the shop catalog (0 = no catalog). shop = the store (domain, platform, top_country, monthly visits estimate, categories). product_url is the product page on spytrend.com (link it); ads_url lists the product's ads. COUNTS ARE PER PRODUCT: never use a shop's active_ads/total_ads from search_shops/get_shop as a product's numbers — they count the WHOLE domain. Filters: q = substring of the product handle, i.e. the URL slug (lower-case words joined by dashes: 'weighted blanket' matches weighted-blanket-queen) — NOT the product title: a product sold as 'CloudAlign Pillow' may live at cloud-alignment-pillow, so when a named product is missing from the rows, retry with a shorter fragment or the compound word split by a dash ('cloudalign' -> 'cloud-align'), or domain= when the shop is known; country = ISO-2 codes (comma separated) of the SHOP's main visitor country, not of the ads — never present it as the country the ads run in; ai_category = Spytrend AD category slugs (comma separated); site_category = estimated site category slug; platform = commerce platform of the shop (comma separated, e.g. Shopify); domain = exact shop domains (comma separated) — use it for 'products of this shop'; active_only=true = only products with an ad active on active_as_of; win_badge = comma separated badges; date_from/date_to (YYYY-MM-DD) = window of Facebook launches ('launched/advertised during a period'): a product matches when one of its ads launched inside the window, and ads_in_period is the number of such launches — this includes old products that relaunched an ad in the window. first_seen_days (1-365) = only products whose FIRST Facebook launch (fb_launch_date) happened in the last N days: for 'first seen / new products / started advertising in the last N days and still active' pass first_seen_days=N + active_only=true — the tool sets the same boundary as the website's 'last N days' preset (today minus N days; the exact date comes back as first_seen_from), so NEVER compute the date yourself, the same wording must give the same window for every country (do not rely on date_from alone); first_seen_from (YYYY-MM-DD) = the same filter for an explicit calendar date the user named ('first seen since 20 September'), not for relative periods; if both are given first_seen_days wins; total then counts only such products (if the result has filter_note, the tool filtered the API pages itself and total is just the number of returned rows). win_badge=testing is the site's badge for 'active, under 14 days in ads'. min_price/max_price filter the catalog price; min_ads/max_ads filter the product's own ads count. sort_by: ads (default), ads_active, ads_in_period (needs a date window), price, visits (shop traffic), score (Winning Products: days x creatives x geos x reuploads). Returns total (the number of matching products — quote it as the number found; the rows are only the first limit of them), has_more, offset and data_through (last day the data is computed for; a date window is cut at it) and active_as_of (date of the daily snapshot the ads_active counters belong to). If a requested window starts after data_through there is no data for it yet: say the data is available through data_through, never print a period whose start is after its end. Rows with access=teaser have their ad counters blanked by the plan. FREE PLAN COUNTS: when the plan's archive window narrows a request, pagination.total_status is "restricted" and meta.plan_window_cutoff names the boundary — the count then describes the window actually searched, NOT the one requested, so a zero means "nothing in the archive window" and never "nothing exists". QUOTA: 1 MCP credit per DELIVERED result from your plan balance (free starter: 500 MCP credits lifetime; paid plans: 40,000/month; short pages auto-refund — you pay only for results you receive). Default page is 20 results = 20 MCP credits; pass limit (1–200) to size it. get_usage is free. Autonomous agents must be linked to a spytrend account to access data — an unlinked agent gets an actionable connect-your-account refusal (create agent credentials at spytrend.com/settings?tab=ai, or a human claims it by client_id), NOT a server error. Calls are rate-limited per authenticated user (deployment defaults: 60/minute and 1000/hour); a rate-limit refusal is an MCP tool error with structured error.code=rate_limit_exceeded, scope, window and retry_after_seconds. CONCURRENCY: heavy analytical calls (get_trends, search_ads, search_creatives) are admitted ONE AT A TIME per account — fanning out 5-10 of them in parallel does not go faster, it returns admission refusals for all but one. Issue heavy calls sequentially; light lookups (get_ad, get_advertiser, get_usage) are not gated. PRICING: price × number of filters set (min 1), on paid plans ×1 after 500 MCP credits/month; one-time consent via accept_pricing_terms; before calling, get the maximum debit from estimate_cost (free) and tell the user.

Input Schema

NameRequiredDescriptionDefault
qNosubstring of the product handle (URL slug): words in lower case joined by dashes, e.g. 'weighted blanket' matches weighted-blanket-queen. Not a shop name and not a free-text search of ad copy.
limitNomax results per call (default 20, at most 100 — the products API serves 100 rows per page; a larger value is reduced to 100 and noted in params.normalized, page further with offset; each delivered result costs 1 MCP credit).
domainNoexact shop domains, comma separated — products of these shops only (e.g. 'mellowsleep.com')
offsetNopagination offset (0-based)
countryNoISO-2 codes, comma separated: keep products of shops whose MAIN visitor country is one of them (not the countries the ads ran in)
date_toNowindow of Facebook launches, end YYYY-MM-DD
max_adsNomaximum number of ads of the product itself (180 days)
min_adsNominimum number of ads of the product itself (180 days)
sort_byNoorder by: ads (default, descending), ads_active, ads_in_period (needs date_from/date_to), price, visits (shop traffic) or score (Winning Products)
platformNocommerce platform of the shop, comma separated: Shopify, WooCommerce, WordPress, Wix, Squarespace, Magento, PrestaShop or BigCommerce
date_fromNowindow of Facebook launches, start YYYY-MM-DD: products with an ad launched inside the window (old products that relaunched included); rows then carry ads_in_period. For 'first seen in the last N days' use first_seen_days instead
max_priceNomaximum catalog price (shop currency)
min_priceNominimum catalog price (shop currency); products without a catalog price drop out
win_badgeNocomma separated Winning Products badges: testing (active, under 14 days in ads), heating (active, 14-29 days), proven (active, 30+ days and 10+ ads), ran30 (30+ days, not proven)
active_onlyNotrue = only products with at least one ad active on active_as_of (the daily data snapshot day returned with the result)
ai_categoryNoSpytrend AD category slugs, comma separated (e.g. ecommerce_and_retail,beauty_and_cosmetics)
site_categoryNoestimated site category slug of the shop (comma separated); may be missing or wrong, ai_category is better for ad-market discovery
first_seen_daysNo1-365: only products whose FIRST Facebook launch (fb_launch_date) was within the last N days — use it for 'new / first seen / started advertising in the last N days'. The tool sets first_seen_from = today minus N days (the website's 'last N days' preset boundary) and returns it as first_seen_from; do not compute the date yourself. Wins over first_seen_from.
first_seen_fromNoYYYY-MM-DD: only products whose FIRST Facebook launch (fb_launch_date) is on or after this date — ONLY for an explicit calendar date the user named; for relative periods ('last N days') use first_seen_days, never compute the date yourself. Ignored when first_seen_days is given. total counts only such products.

Output Schema

NameRequiredDescriptionDefault
dataNo
errorNoPresent only when isError is true: machine-readable failure. The human explanation stays in content.
totalNo
offsetNo
paramsNoRequest parameter echo: applied = parameters that shaped this result; normalized = parameters rewritten before applying (alias, type coercion, resolved id); ignored = parameters that were accepted but NOT applied, with the reason.
has_moreNo
addon_hintsNoAdd-on modules that have additional data for objects of this result (no prices, no paid values). subscription_status=active: the account has the module — use its normal path. Do not push a purchase the user did not ask about.
filter_noteNo
period_axisNo
window_noteNo
active_as_ofNo
data_throughNo
scanned_rowsNo
country_basisNo
first_seen_fromNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedInput schema / properties / limit / description
      Previous value: -"max results per call (default 20, at most 100 — the products API serves 100 rows per page; a larger value is reduced to 100 and noted in params.normalized, page further with offset; each delivered result costs 1 token)."New value: +"max results per call (default 20, at most 100 — the products API serves 100 rows per page; a larger value is reduced to 100 and noted in params.normalized, page further with offset; each delivered result costs 1 MCP credit)."
    • addedOutput schema / properties / addon_hints
      Added value: +{
      +  "description": "Add-on modules that have additional data for objects of this result (no prices, no paid values). subscription_status=active: the account has the module — use its normal path. Do not push a purchase the user did not ask about.",
      +  "items": {
      +    "properties": {
      +      "available_data_types": {
      +        "description": "kinds of data the module confirmedly has for the object",
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "info_url": {
      +        "description": "the object (or its limited breakdown) inside the module on spytrend.com",
      +        "type": "string"
      +      },
      +      "module": {
      +        "description": "nutra | crypto | web2app | search_arb | startups",
      +        "type": "string"
      +      },
      +      "object_id": {
      +        "description": "the ad id, or the site domain for site rows",
      +        "type": "string"
      +      },
      +      "preland_downloadable": {
      +        "description": "Nutra / Crypto: the saved pre-lander can be downloaded in the module",
      +        "type": "boolean"
      +      },
      +      "subscription_status": {
      +        "description": "active | not_connected",
      +        "type": "string"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
  2. Changed7 schema fields changed
    • changedInput schema / properties / active_only / description
      Previous value: -"true = only products with at least one active ad now"New value: +"true = only products with at least one ad active on active_as_of (the daily data snapshot day returned with the result)"
    • changedInput schema / properties / date_from / description
      Previous value: -"window of Facebook launches, start YYYY-MM-DD: products with an ad launched inside the window (old products that relaunched included); rows then carry ads_in_period. For 'first seen in the last N days' use first_seen_from instead"New value: +"window of Facebook launches, start YYYY-MM-DD: products with an ad launched inside the window (old products that relaunched included); rows then carry ads_in_period. For 'first seen in the last N days' use first_seen_days instead"
    • addedInput schema / properties / first_seen_days
      Added value: +{
      +  "description": "1-365: only products whose FIRST Facebook launch (fb_launch_date) was within the last N days — use it for 'new / first seen / started advertising in the last N days'. The tool sets first_seen_from = today minus N days (the website's 'last N days' preset boundary) and returns it as first_seen_from; do not compute the date yourself. Wins over first_seen_from.",
      +  "type": "integer"
      +}
    • changedInput schema / properties / first_seen_from / description
      Previous value: -"YYYY-MM-DD: only products whose FIRST Facebook launch (fb_launch_date) is on or after this date — use it for 'first seen / started advertising in the last N days' (date_from alone also returns old products that merely launched another ad in the window). total counts only such products."New value: +"YYYY-MM-DD: only products whose FIRST Facebook launch (fb_launch_date) is on or after this date — ONLY for an explicit calendar date the user named; for relative periods ('last N days') use first_seen_days, never compute the date yourself. Ignored when first_seen_days is given. total counts only such products."
    • changedInput schema / properties / limit / description
      Previous value: -"max results (default 20; each delivered result costs 1 token)."New value: +"max results per call (default 20, at most 100 — the products API serves 100 rows per page; a larger value is reduced to 100 and noted in params.normalized, page further with offset; each delivered result costs 1 token)."
    • addedOutput schema / properties / active_as_of
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / window_note
      Added value: +{
      +  "type": "string"
      +}
  3. Added

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, it discloses quota costs, credit charging, rate limits, concurrency admission behavior, pricing mechanics, teaser blanking, free-plan archive restrictions, and the active_as_of snapshot semantics. These are material behavioral traits that an agent would otherwise not know from schema or annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The content is relevant and front-loaded, but the description is a very long, dense paragraph that is difficult to scan and repeats some schema details. Global pricing, quota, and concurrency notes are useful but make the definition heavy for a single tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 19 optional parameters, rich annotations, and an output schema, the description covers the operational context an agent needs: filtering semantics, pagination, totals, snapshot dates, quota costs, and edge cases. No critical calling information appears to be missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is already 100%, the description adds substantial semantic guidance beyond the schema: q is a handle substring and not a title search, country is the shop's main visitor country and not the ad country, first_seen_days takes precedence over first_seen_from, and date_from/date_to describe launch-window matches including relaunches. It also clarifies total vs returned rows and special restricted-count behavior.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise verb and resource: searching e-commerce products that ads lead to. It defines the row granularity as one product page per shop and contrasts product counts with shop-level counts from search_shops/get_shop, so an agent can distinguish it from sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use guidance for many ambiguous cases: q vs domain, first_seen_days vs first_seen_from, date windows vs first-seen filters, and active_only combined with first_seen_days. It also warns against using shop-level active_ads/total_ads as product counts and explains how to handle named products missing from handle search.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.