Business boundary
The supplied offer, customer and exclusions define direct competitive fit before discovery.
Input scopeThis workflow returns 3–5 verified direct competitors.
Choose a niche and describe what you sell. The workflow finds advertisers in that market, checks each one against a real ad and advertiser profile, and keeps directories, lead networks and adjacent businesses out of the shortlist.
Example run · 13 Oct 2026 · ~2 min
Prompts update as you change the inputs
Turn the niche and focus into a clear rule for who counts as a direct competitor and who does not.
View promptHide promptUse the connected Spytrend MCP to define the direct-competitor boundary. Supported niche: home_services Focus: Roof replacement contractors Country (ISO-2): US Lookback: 30 days of completed UTC days ending yesterday End the window on the latest complete UTC day. Define a direct competitor at the company level from the supplied focus. Exclude directories, publishers, affiliates, lead networks, agencies, marketplaces and materially adjacent offers unless explicitly included by the focus. Derive and retain one or two short high-intent product/service phrases from the focus; never use the full focus sentence as a search query. Keep the category, focus, country and lookback fixed. Do not run discovery in this step. Return no more than three concise bullets: confirmed scope and exact completed-date window; inclusion/exclusion boundary plus retained phrases; evidence gates. Do not show plan, quota, token balance, raw parameters or internal identifiers. Stop after Step 1.
Search the niche and a few short product phrases, then merge duplicate advertisers.
View promptHide promptCost guard: before each paid Spytrend call, run the free `estimate_cost` with the same tool and arguments, estimate the cost and stay within the user's stated budget; if the user has not stated a budget, tell them the estimate before the first paid call. If pricing consent is required, show the returned terms and stop until the customer explicitly agrees; never accept on the customer's behalf. If a required call does not fit the stated budget, make no paid call and return `Budget limit prevents required research`; omit an optional call that does not fit and disclose reduced coverage. When opening ads with `get_ad`, skip multilang ads (`is_multilang`) and never call `get_media` after `get_ad`. Retry once only when `retryable=true`, after `retry_after_seconds`. Read `params.ignored` after every search; an ignored required filter never counts as applied. If a search reports `pagination.total_status=restricted` (a free-plan archive window; `meta.plan_window_cutoff` names the boundary), tell the user the result covers only ads that started on or before that date, and never report a zero from it as "no such ads exist". Cost notices are not part of the final customer report. Use the connected Spytrend MCP to discover candidate advertisers for the retained scope. Run one primary heavy discovery route, chosen by the focus. 1. Focus set: run one `search_ads` with query = the first retained phrase, source Meta, categories=[home_services], countries=[US], status_today=active, the retained completed-day launch window, sort_by=date and limit=20. Run the second retained phrase the same way only when the first returns fewer than five plausible direct-fit advertisers. Do not use the niche-wide advertiser ranking when the focus is set; it rarely contains focus-specific businesses. 2. Focus blank: get the Meta advertiser ranking using the exact supported top-level category home_services, country US, dimension=advertisers, min_geo_share=0.5, min_category_share=0.3, sort_by=active_ads and limit=10. Do not add an AI subcategory; never infer one from customer text. Deduplicate by advertiser identity and keep distinct pages separate unless evidence proves one company. Drop obvious info-guide, grant-assistance and lead-network pages. Retain up to eight candidates in returned order, each with its matching discovery ad when there is one. Discovery order is a signal, not proof of competitor fit, company size or performance. If a discovery call returns retryable=true with retry_after_seconds, wait that delay and retry once identically. A final failure makes that configured route unavailable and the run Partial while unaffected routes continue. A completed zero is valid zero evidence; unavailable is never zero. Return no more than eight concise bullets: route outcomes, delivered and deduplicated counts, and retained candidate names with source type. Retain exact IDs internally for Step 3 but never render full, shortened, masked or partial IDs. Do not show tables, calls, parameters, quota, token usage or rejected-row dumps. Stop after Step 2.
Open a relevant ad and the advertiser profile for every candidate before it can enter the shortlist.
View promptHide promptCost guard: before each paid Spytrend call, run the free `estimate_cost` with the same tool and arguments, estimate the cost and stay within the user's stated budget; if the user has not stated a budget, tell them the estimate before the first paid call. If pricing consent is required, show the returned terms and stop until the customer explicitly agrees; never accept on the customer's behalf. If a required call does not fit the stated budget, make no paid call and return `Budget limit prevents required research`; omit an optional call that does not fit and disclose reduced coverage. When opening ads with `get_ad`, skip multilang ads (`is_multilang`) and never call `get_media` after `get_ad`. Retry once only when `retryable=true`, after `retry_after_seconds`. Read `params.ignored` after every search; an ignored required filter never counts as applied. If a search reports `pagination.total_status=restricted` (a free-plan archive window; `meta.plan_window_cutoff` names the boundary), tell the user the result covers only ads that started on or before that date, and never report a zero from it as "no such ads exist". Cost notices are not part of the final customer report. Use the connected Spytrend MCP to verify up to five retained candidate companies without rerunning discovery. Take plausible direct-fit advertisers in returned order, up to five, so that 3–5 competitors can survive verification. For each, open its matching non-multilang (`is_multilang`) discovery ad once with `get_ad`. Only when discovery returned no matching ad, first run one candidate-specific `search_ads` with its exact advertiser ID, source Meta, countries=[US], active status, the retained completed-day window, date descending and `limit=3`, then open the best-matching non-multilang row once. When the ad qualifies, call its advertiser profile once for the company name and global active-ad count. Include a competitor only when the detailed ad is active, includes US, has a Facebook start date inside the exact window, explicitly promotes Roof replacement contractors, and retained evidence resolves company identity. Confirm the first-party landing relationship separately. Label advertiser-wide active-ad counts as global. Exclude taxonomy-only matches, adjacent offers and unresolved company identities. Deduplicate verified pages into one company only when brand/domain evidence supports it. Do not open a second ad for the same candidate. If a selected ad-detail or advertiser-detail call returns retryable=true with retry_after_seconds, wait that delay and retry once identically. A final call failure, ignored required filter or required budget block makes the run Partial. A completed detail that does not qualify the candidate and a missing optional landing field keep the run Complete; never replace a candidate after its ad is opened. Retain full evidence internally. Return no more than eight concise bullets: verified, unresolved and excluded counts plus one short evidence summary per verified or useful unresolved company. Do not show raw IDs, calls, parameters, quota, token usage or detailed rejected-row dumps. Stop after Step 3.
Show only verified direct competitors, with the ad that proves each one and what to analyze next.
View promptHide promptUsing retained evidence only, write the final customer report without rerunning Spytrend. Keep the complete answer under 380 words and table-free. Do not show raw IDs, category slugs, search phrases, calls, route names, quotas, token usage or detailed exclusions. Start with `# Competitors Running Meta Ads: Roof replacement contractors in ` followed by the full country name for US (write United States, not US; if the focus is blank, use the human-readable niche name, never its slug), then one summary line with verified competitor count, completed-day window and Complete/Partial. Complete means every configured discovery and selected verification call completed successfully. A bounded sample or unresolved individual candidate does not make the run Partial. Use Partial only for a failed required route/call or unresolved required filter. Show 3–5 compact numbered competitors when that many qualify; never pad. Include company, observed offer, active selected-country launch date, advertiser-wide active count labeled global, plain-text domain/landing confidence and exactly one review action. Add `## Needs verification` only when populated, maximum one one-sentence entry. Add `## What stands out` with at most two bullets, `## Analyze next` with at most two companies and `## Research coverage` with at most two bullets. Do not claim that ranking order or global active counts measure company size, selected-country activity or performance. End exactly: `Ad activity is a market signal, not proof of demand, spend, conversions, revenue, ROAS or profitability.` Stop after Step 4.
Cost guard: before each paid Spytrend call, run the free `estimate_cost` with the same tool and arguments, estimate the cost and stay within the user's stated budget; if the user has not stated a budget, tell them the estimate before the first paid call. If pricing consent is required, show the returned terms and stop until the customer explicitly agrees; never accept on the customer's behalf. If a required call does not fit the stated budget, make no paid call and return `Budget limit prevents required research`; omit an optional call that does not fit and disclose reduced coverage. When opening ads with `get_ad`, skip multilang ads (`is_multilang`) and never call `get_media` after `get_ad`. Retry once only when `retryable=true`, after `retry_after_seconds`. Read `params.ignored` after every search; an ignored required filter never counts as applied. If a search reports `pagination.total_status=restricted` (a free-plan archive window; `meta.plan_window_cutoff` names the boundary), tell the user the result covers only ads that started on or before that date, and never report a zero from it as "no such ads exist". Cost notices are not part of the final customer report. Use the connected Spytrend MCP to find likely direct competitors currently running Meta ads in the controlled niche and country. Inputs: - Niche (category slug, never shown to the customer): home_services - Direct competitor focus: Roof replacement contractors - Country (ISO-2): US - Lookback: 30 days of completed UTC days ending yesterday Complete all research in one turn and return only the final customer report. Apart from mandatory pre-call cost notices, do not emit intermediate step responses or stop after validation. Use Meta only, read-only, and run heavy calls sequentially. Validate the controlled category, focus, country and lookback. If invalid, return exactly `Invalid controlled input configuration` without an MCP call. Calculate the window: the last 30 days of completed UTC days, ending yesterday (exclude the open UTC date). Define a direct competitor at company level from Roof replacement contractors. Exclude directories, publishers, affiliates, lead networks, agencies, marketplaces and materially adjacent offers unless the controlled focus explicitly includes them. Derive one or two short high-intent product/service phrases from the focus; never use the full focus sentence as a query or generate broad synonyms. Run one required primary discovery route, chosen by the focus. Focus set: run one `search_ads` with query = the first derived phrase, source Meta, categories=[home_services], countries=[US], status_today=active, the exact completed-day launch window, sort_by=date and limit=20; run the second phrase the same way only when the first returns fewer than five plausible direct-fit advertisers. Do not use the niche-wide advertiser ranking when the focus is set. Focus blank: get the advertiser ranking for the exact supported top-level home_services and US, with dimension=advertisers, min_geo_share=0.5, min_category_share=0.3, sort_by=active_ads and limit=10. Do not add an AI subcategory; never infer one from customer text. Deduplicate by advertiser identity. Keep distinct pages separate unless current evidence proves one company. Drop obvious info-guide, grant-assistance and lead-network pages. Retain up to eight candidate advertisers in returned order, each with its matching discovery ad when there is one. Discovery order and advertiser-wide counts are discovery signals, not proof of direct fit, company size or performance. Take plausible direct-fit advertisers in returned order, up to five, so that 3–5 competitors can survive verification. For each, open its matching non-multilang (`is_multilang`) discovery ad once with `get_ad`. Only when discovery returned no matching ad, first run one candidate-specific `search_ads` with its exact advertiser ID, source Meta, countries=[US], active status, the exact completed-day window, date descending and `limit=3`, then open the best-matching non-multilang row once. When the ad qualifies, call its advertiser profile once for the company name and global active-ad count. Include the company only when the detailed ad confirms active status, US, a Facebook start date inside the completed-day window and an offer directly matching Roof replacement contractors, and retained evidence resolves company identity. Confirm the first-party landing relationship separately. Exclude taxonomy-only matches, adjacent offers, inactive or wrong-country ads, dates outside the window and unresolved company identities. Merge pages into one company only when brand/domain evidence supports it. Do not open a second ad for the same candidate. When any required call returns retryable=true with retry_after_seconds, wait that delay and retry once identically. A final call failure, ignored required filter or required budget block makes the run Partial while unaffected work continues. A completed zero, completed non-qualifying detail, missing optional landing field, bounded rows and an unresolved individual candidate are coverage limits and keep the run Complete. Write a table-free customer report under 380 words. Start with `# Competitors Running Meta Ads: Roof replacement contractors in ` followed by the full country name for US (write United States, not US; if the focus is blank, use the human-readable niche name, never its slug), then show verified competitor count, exact completed-day window and Complete/Partial. Show 3–5 compact numbered competitors when that many qualify; never pad. Include company, observed offer, active selected-country launch date, advertiser-wide active count explicitly labelled global, domain/landing confidence and exactly one review action. Add `Needs verification` only when populated, maximum one entry; `What stands out` with at most two sample-specific bullets; `Analyze next` with at most two companies; and Research coverage with at most two bullets. Hide service name, category slugs, search phrases, route names, raw IDs, calls, parameters, quotas, token usage, timing, retries and detailed exclusions. Do not imply ranking order or global counts measure company size, selected-country activity or performance. Do not infer demand, spend, conversions, revenue, ROAS, profitability, market share or complete market coverage. End exactly: `Ad activity is a market signal, not proof of demand, spend, conversions, revenue, ROAS or profitability.`
A live run on 13 Oct 2026 used Home Services, United States, a 30-day window and the focus “Roof replacement contractors.” Four local roofing contractors qualified, and all four are shown here.
| Competitor | Why it qualifies | Identity and evidence |
|---|---|---|
| 01ExteriorStage | Owner-led ad for full roof replacement from $5,997, launched in the window and active in the US. | Confirmed advertiserOwn site: quote.exteriorstage.comActive ads, global: 78 |
| 02Roofs Only FL | Roof replacement in Southwest Florida with a $2,597 discount and help with insurance paperwork. | Confirmed advertiserOwn site: roofsonlyfldeals.comActive ads, global: 3 |
| 03Reeder Roofing LLC | Free roof replacement inspection for homeowners in Birmingham, Alabama. | Confirmed advertiserLanding: Facebook lead formActive ads, global: 3 |
| 04JDK Contractors | Roof replacement and repairs in Philadelphia, with a free quote and 10% off this month. | Confirmed advertiserLanding: Facebook lead formActive ads, global: 2 |
Published by Spytrend from a dated, bounded example.
The supplied offer, customer and exclusions define direct competitive fit before discovery.
Input scopeA bounded Meta search returns candidate advertisers in the selected category and country.
DiscoveryA detailed ad and advertiser profile must support identity, offer and direct relevance.
VerificationDirectories, lead networks and adjacent businesses stay outside the final shortlist.
Evidence boundaryThe advertiser and its Facebook page, the offer in the opened ad, country, current status, landing domain and a representative ad.
Why a candidate fits your definition of a direct competitor and which advertisers deserve a deeper look.
This is a short verified list, not every competitor in the market. A link the data cannot confirm is marked Not confirmed.
Searching a Facebook ad library by keyword returns everyone who used the word: agencies, directories, lead networks and businesses that only sit near your niche. This workflow starts from the same kind of search in Spytrend and then filters it the way a marketer would, by what each advertiser actually sells.
Every competitor on the list has passed two checks: an active ad in your country that matches your product or service, and an advertiser profile that belongs to the same business. You get fewer names than a raw search, but each one is someone you actually compete with for the same customer.
Spytrend data this workflow usesThe workflow searches your niche and a few short phrases that describe your product, merges duplicate advertisers, then opens a real ad and the advertiser profile for each candidate before it can enter the list.
No. It is a short verified list for the niche, country and period you chose. The workflow returns fewer than five names when the evidence is weak rather than padding the list.
A confirmed advertiser can send traffic through a third-party booking or lead form. Who the business is and where its ads lead are different questions, so each gets its own confidence.
They are left out of the direct-competitor list unless your focus asks for that type of business.
Use the competitor ad analysis workflow: enter the domain and get their offers, messages and the ads worth opening first.
Choose the niche, describe the competitor, then run the four prompts in your AI assistant.