Skip to main content
Glama

Search webmasters

search_webmasters
Read-only

Search webmasters (affiliates) — a webmaster is a whole ad NETWORK (landing domains, pixels, pages and geos grouped as one). Copy workflow: search by domain, take the canonical UUID, then search_creatives/search_ads with webmaster_id. Finish with the most reused material: get_webmaster.top_creatives or search_creatives sort_by=total_ads; total_ads is how many ads reuse the same material over its lifetime, not a weekly debut count. Returns total/active counts, top countries and geo counts. Find by name or pixel_id/domain/page_id/resolved_ip. Filter by category, AI category/subcategory, countries, languages, platforms, format, current status, dates and count ranges. For a geo ranking combine countries + min_geo_share + sort_by=relevance. Save returned UUIDs with add_to_favorites. Exact pixel_id/domain/page_id/resolved_ip lookups use the webmaster's CURRENT canonical identifier membership; historical identifiers removed from a webmaster do not count as matches. Exact page_id results report fanpages_status as available, partial, unavailable or not_applicable. When available, the selected page is included in fanpages[] with life_status from the same page-lifetime source as /advertisers (alive/deleted/banned, or unknown when lifetime coverage has no row); when unavailable, an omitted fanpages[] is not evidence that the page is alive. 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 token per DELIVERED result from your plan balance (free starter: 500 tokens lifetime; paid plans: 40,000/month; short pages auto-refund — you pay only for results you receive). Default page is 20 results = 20 tokens; 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. TIKTOK SOURCE: pass source="tiktok" to query the TIKTOK ad corpus instead of Meta. (The platforms filter does NOT do this — platforms are Meta publisher placements.) ⚠️ TIKTOK IS PAID PER ROW at a premium: every DELIVERED TikTok ad row costs 100 tokens and every TikTok webmaster row/card costs 100 tokens (Meta rows cost 1), deducted from the same token balance (paid plans: 40,000/month = up to 400 TikTok rows). Request small limits and narrow filters; you are charged only for rows actually delivered (short pages auto-refund; if the balance covers only part of the request, that part is delivered — a 3-row request on a 150-token balance returns 1 row and charges 100). TikTok requires a Pro-or-higher plan: free/starter callers and unlinked agents get an actionable upgrade refusal, never data and never a charge. TikTok rows have their OWN shape, returned under tiktok_data (verified live 2026-07-30): id/external_id (TikTok ad id), advertiser{id,external_id,name} plus advertiser_id (TikTok BUSINESS id), start_date/end_date (the ad's delivery window) and first_seen_date/last_seen_date (Spytrend indexing), days_active, is_active + status_today, ai_category/ai_subcategory, countries + targeting_geos + targeting_details (OS/age/gender/regions), audience_size, objective, sponsor (the 'paid for by' funder) and registry_location, landing_domain + link_url, body/title/call_to_action, creative_format, creative_id, creative_ad_count (how many ads reuse that creative), is_blurred/is_cloaked, and media[] with media_type + thumbnail_url on media-tt.spytrend.com. Media comes WITH the row — do NOT call get_media for TikTok ids (it serves Meta entities only). There are no TikTok engagement counters (plays/likes/comments/shares) on this surface. The TikTok feed serves the ARCHIVED TikTok corpus — exactly what the spytrend.com /ads TikTok tab shows — and pagination carries has_more/next_cursor plus total with total_status (exact, estimated or unavailable; unavailable is not zero). With source=tiktok rows are TikTok webmaster clusters. Supported TikTok webmaster filters: query, domain, countries (+min_geo_share), exclude_countries, ai_category (dominant), min_total_ads, min_active_ads, date_from/date_to, has_funder, sort_by=total_ads|active_ads|created_at|relevance, sort_order, offset (0-5000), limit (server caps TikTok at 100). Date filters select clusters whose activity window overlaps the requested period. Active means shown within the last 3 calendar days. Meta-only lookups, languages/platforms/creative_format(s), status_today, ai_subcategory, folder_id and saved are REJECTED before charging. Default TikTok limit is 10; each delivered row costs 100 tokens.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
limitNomax results (default 20; each delivered result costs 1 token).
queryNofree-text webmaster (affiliate) name to search for
savedNosaved scope selector. Use saved=all to restrict results to webmasters saved in ANY favourites folder.
domainNopoint lookup: webmasters on this landing domain
offsetNopagination offset — skip the first N rows. The /webmasters ranking pages by offset (not a cursor), so this is how a caller reaches page two and beyond. Max 5000.
sourceNowebmaster corpus: meta (default — Facebook/Meta networks, 1 token per delivered row) or tiktok (TikTok business-id clusters — ⚠️ PAID: 100 tokens per DELIVERED row; Pro plan required; default limit drops to 10, server caps TikTok at 100)
date_toNoonly webmasters active on or before this date (YYYY-MM-DD)
page_idNoexact current-ownership lookup by Facebook page id (a pasted facebook.com page link in any form is also accepted and resolved to the canonical page id); fanpages_status reports lifecycle coverage and available results include alive/deleted/banned/unknown lifecycle
sort_byNoorder by: total_ads (default), active_ads or relevance (relevance ranks by ad-VOLUME in the selected countries — geo-relevance; needs countries)
categoryNovertical filter: gambling or other
pixel_idNopoint lookup: webmasters using this Facebook pixel id
countriesNoISO country codes the webmaster's ads ran in
date_fromNoonly webmasters active on or after this date (YYYY-MM-DD)
folder_idNorestrict results to webmasters saved in this favourites folder UUID. Mirrors the /webmasters folder view.
languagesNolanguage codes filter
platformsNoplatform names filter (e.g. facebook, instagram)
has_funderNoTikTok only (source=tiktok): keep only clusters with an EXTERNAL 'paid for by' sponsor (the funded-by filter). Rejected for the Meta corpus.
sort_orderNosort direction: asc or desc (default desc)
ai_categoryNoAI category slug filter (e.g. gambling_and_betting)
resolved_ipNopoint lookup: webmasters whose domain resolves to this IP
status_todayNocurrent status: active, inactive or vanished
min_geo_shareNoGEO-RELEVANCE gate (0-1, the relevant-only toggle): keep only webmasters where the 'countries' you pass are at least this fraction of their ads — i.e. that geo is their DOMINANT geo (e.g. 0.5 = country >=50% of their ads). Without it, countries is a mere 'present-in' match and a webmaster with 0.5% of ads in BR ranks as a 'BR webmaster'. Requires countries. Each returned row's geo field carries the per-country ad-count breakdown so you can read the real exposure.
min_total_adsNoonly webmasters with at least this many total ads
ai_subcategoryNoAI subcategory slug filter
min_active_adsNoonly webmasters with at least this many ACTIVE ads
creative_formatNosingle creative format filter (legacy form). Prefer creative_formats[] — the visible /webmasters control is a multi-select.
creative_formatsNocreative formats to include (video, carousel, single, dynamic). Mirrors the visible /webmasters format multi-select.
exclude_countriesNoISO country codes to EXCLUDE — drops webmasters whose ads run in ANY of them. Mirrors the /webmasters geo EXCLUDE column; combine with countries to keep one market while removing noise markets.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
dataNo
metaNo
errorNoPresent only when isError is true: machine-readable failure. The human explanation stays in content.
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.
sourceNo
paginationNo
tiktok_dataNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changed
    • addedOutput schema / properties / error
      Added value: +{
      +  "description": "Present only when isError is true: machine-readable failure. The human explanation stays in content.",
      +  "properties": {
      +    "code": {
      +      "description": "fine-grained, stable failure code (e.g. invalid_arguments, backend_busy)",
      +      "type": "string"
      +    },
      +    "kind": {
      +      "description": "failure class: invalid_argument, not_found, permission_denied, unauthenticated, quota_exceeded, rate_limited, temporarily_unavailable, unavailable_until_ready, unsupported, internal",
      +      "type": "string"
      +    },
      +    "message": {
      +      "description": "the same human text as content[0]",
      +      "type": "string"
      +    },
      +    "outcome": {
      +      "description": "activity-feed outcome class",
      +      "type": "string"
      +    },
      +    "param": {
      +      "description": "the request parameter the failure is about, when known",
      +      "type": "string"
      +    },
      +    "retry_after_seconds": {
      +      "description": "wait this long before retrying",
      +      "type": "integer"
      +    },
      +    "retryable": {
      +      "description": "true when repeating the SAME call can succeed (after retry_after_seconds when present)",
      +      "type": "boolean"
      +    }
      +  },
      +  "type": "object"
      +}
    • addedOutput schema / properties / params
      Added value: +{
      +  "description": "Request 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.",
      +  "properties": {
      +    "applied": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "ignored": {
      +      "items": {
      +        "properties": {
      +          "param": {
      +            "type": "string"
      +          },
      +          "reason": {
      +            "type": "string"
      +          },
      +          "to": {
      +            "description": "the parameter it was applied as, when renamed",
      +            "type": "string"
      +          },
      +          "value": {
      +            "description": "the value actually applied, when rewritten",
      +            "type": "string"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "normalized": {
      +      "items": {
      +        "properties": {
      +          "param": {
      +            "type": "string"
      +          },
      +          "reason": {
      +            "type": "string"
      +          },
      +          "to": {
      +            "description": "the parameter it was applied as, when renamed",
      +            "type": "string"
      +          },
      +          "value": {
      +            "description": "the value actually applied, when rewritten",
      +            "type": "string"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "type": "array"
      +    }
      +  },
      +  "type": "object"
      +}
    • removedOutput schema / required
      Removed value: -[
      -  "data",
      -  "pagination"
      -]
  2. Changed10 schema fields changed
    • addedOutput schema / properties / data / items / properties / ai_categories
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": [
      +    "null",
      +    "array"
      +  ]
      +}
    • addedOutput schema / properties / data / items / properties / domains
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": [
      +    "null",
      +    "array"
      +  ]
      +}
    • addedOutput schema / properties / data / items / properties / domains_count
      Added value: +{
      +  "type": "integer"
      +}
    • addedOutput schema / properties / data / items / properties / page_ids
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": [
      +    "null",
      +    "array"
      +  ]
      +}
    • addedOutput schema / properties / data / items / properties / stats_refreshed_at
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / data / items / properties / stopped_ads
      Added value: +{
      +  "type": "integer"
      +}
    • addedOutput schema / properties / data / items / properties / top_countries
      Added value: +{
      +  "items": true,
      +  "type": [
      +    "null",
      +    "array"
      +  ]
      +}
    • addedOutput schema / properties / data / items / properties / windowed_active_ads
      Added value: +{
      +  "type": "integer"
      +}
    • addedOutput schema / properties / data / items / properties / windowed_stopped_ads
      Added value: +{
      +  "type": "integer"
      +}
    • addedOutput schema / properties / data / items / properties / windowed_total_ads
      Added value: +{
      +  "type": "integer"
      +}
  3. First observed

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already declare readOnlyHint/openWorldHint, and the description strongly reinforces and enriches them: token pricing per delivered row, free-plan archive-window restriction semantics ('a zero means nothing in the archive window and never nothing exists' — consistent with openWorldHint), rate-limit refusal structure (error.code=rate_limit_exceeded), one-at-a-time concurrency gating for heavy calls, agent-linking requirements, and TikTok premium charging. All of this goes well beyond the structured annotations. No contradiction.

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

Conciseness2/5

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

The description is a single ~1,400-word wall of text with no section breaks, headings, or bullet structure, mixing core workflow, quota math, rate-limit details, concurrency rules, and a full TikTok row shape dump in one undifferentiated block. Nearly every sentence carries real information, but the size and lack of structure make it far harder for an agent to parse than it should be.

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?

For a tool with 28 parameters, two corpora (Meta/TikTok), a pricing model, and rate limiting, the description is extraordinarily complete: it covers result shapes under tiktok_data, refusal behaviors in both normal and free-plan cases, quota mechanics (including auto-refund and partial delivery), pagination semantics (has_more/next_cursor, total_status), and what NOT to do (don't call get_media for TikTok ids). An output schema exists, and the description fills the remaining behavioral gaps comprehensively.

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

Parameters4/5

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

Schema coverage is 100%, so baseline is 3, but the description adds genuine cross-parameter meaning: the countries+min_geo_share+sort_by=relevance combination, which parameters are rejected for TikTok before charging, default limit changes (20→10 for TikTok), and page_id fanpages_status semantics. It explains how parameters interact rather than restating their individual schemas.

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 specific verb+resource ('Search webmasters (affiliates)') and immediately defines the domain ('a webmaster is a whole ad NETWORK'). It differentiates from sibling tools by naming the follow-up workflow ('search_creatives/search_ads with webmaster_id') and the alternative (get_webmaster.top_creatives), so an agent can distinguish it from search_advertisers and search_creatives without opening schemas.

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?

Gives an explicit copy workflow ('search by domain, take the canonical UUID, then search_creatives/search_ads with webmaster_id'), a geo-ranking recipe ('combine countries + min_geo_share + sort_by=relevance'), and clear alternative routing. It also states when the TikTok corpus should be used versus Meta and which filters are rejected for TikTok, leaving little to inference.

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.