Kaufman Lab · AI architecture
Market research

AI Competitor Analyst

A program crawls competitors' websites and puts their prices, timelines and promises into one table. In one niche, monthly prices on the 29 sites that opened varied tenfold: 15,000 to 150,000 RUB (about $175–1,750).

Volume30 websites in the niche
Running cost$0 · 175 credits
Market rate$7,200/mo — analyst
VerdictWorks

Published Aug 25, 2026 · figures checked Sep 1, 2026

How to analyze competitors with AI: eight steps

  1. Niche and city. Name them precisely: "website promotion, Moscow". This one line shapes the whole list.
  2. Company list. Collect every company the search turns up, not just the three best-known names. Our run found 76 companies.
  3. Manual cleanup. Strike out aggregators, directories and companies from other niches. 30 of the 76 remained. This is the only manual step.
  4. What to compare. Write down the attributes before collecting anything: price, timeline, request form, calculator, promises.
  5. Page collection. Take the home page and several inner pages, starting with prices and plans, or you will collect nothing but menus.
  6. A quote is required. Ask for answers with a quote only: "quote the place where the page states the price". No quote, no answer.
  7. Quote check. Verify that the quote is not empty, that it contains an amount or a timeline, and that these numbers actually appear on the page.
  8. One table. Put everything into one table and look at the spread. In our run, prices differed tenfold: from 15,000 to 150,000 RUB (about $175–1,750).

Which setup fits which task

  • One-off niche review: the free limits and one evening are enough.
  • Price monitoring: you need a fixed list of URLs and a schedule, or the data goes stale within a month.
  • A niche without websites: if competitors live on social media and marketplaces, this method does not fit.

Below is a live run on 30 websites: what it showed and what it cost.

01 · Stages

Where the project is now

DoneMethodten steps from an empty folder to a project card
DoneCoderun.py: 835 lines, dashboard.py: 588 lines
DoneRunAug 21, 2026: 30 sites, 29 opened, 175 credits
DoneDashboard24 niche attributes from saved texts, 0 credits
DoneMigrationAug 24, 2026: code in the repo, keys outside git
NowNext nichelegal services, a sample of 50 sites

The service is built, has run on live data and left verifiable artifacts behind. The code is two files: run.py (835 lines) does the measurement, and dashboard.py (588 lines) builds a niche map on top of it without downloading the pages again.

The production run took place on August 21, 2026, in the niche "website promotion, Moscow": 30 sites on the list, 175 Firecrawl credits, about 45 minutes. The duration is reconstructed from the timestamps of the raw files, since the log has none. The same evening, at 18:23, the dashboard was built from the texts already downloaded, for zero Firecrawl credits and 29 extra model calls.

Still to do: the run on the niche named on the service card (legal services, a sample of 50). Two items remain open. One is a beta run by a newcomer who works from the files alone, without the author's help. The other is a mismatch between documentation and code: the instructions tell a person to set up a key for Yandex Cloud, Yandex's cloud platform, while the working script calls OpenRouter.

02 · Task

What was needed

The goal: see what the whole niche tells a client, not just the three best-known competitors. Contractors price this work per competitor. Demis Group, a Russian marketing agency, publishes a price list of 26,000 RUB for three competitors, 53,000 RUB for five and 72,000 RUB for seven (about $300, $620 and $840). Checking fifty sites by eye at ten minutes each takes a full working day without a break.

The constraint that shaped the whole design: a model confirms what it was asked about, not what is on the page. Asked whether a page answers the client, it agrees out of politeness almost everywhere, and the measurement ends up measuring its agreeableness. The literature calls this sycophancy (Sharma et al., 2023).

Hence one rule for its answers: no "yes" without a verbatim quote, and no quote without a number the code has found in the page text. In the August 21, 2026 run, 20 of 29 sites passed these checks, and for all twenty the quote sits in its own column of the table, ready to be opened and checked by hand.

MethodWhat we took from itCanonical name · source
Measure before explainingthe sample size and the client's question are declared before the first command. A sample chosen after the results is no longer a measurementPreregistration of sample and questionNosek et al., PNAS, 2018
Acceptance by thresholdsthree outcomes, set by the number of sites that opened, are named before the start: 40 or more allows percentages, 25–39 allows absolute numbers only, below 25 means plan BPreregistered criteria; small-sample ruleNosek et al., PNAS, 2018
Exact match instead of trusta model's "yes" stands only if the numbers from its quote are found in the page text. Digits are compared, not wordingQuote verification by number (faithfulness)Es et al., "RAGAS", 2023
Split by verifiabilitythe model judges where judgment is needed; price, form and calculator are found by code from a dictionary, a check a person can repeat in a secondDictionary-based content analysis with a codebookKrippendorff, "Content Analysis", 2004
Loud failure instead of silentevery check has three states: yes, no, not checked. An empty cell is not a "no", and a site that did not open counts in neither the numerator nor the denominatorThree-valued logic: yes, no, not checkedCodd, ACM TODS, 1979
Bounded agent loopthe contractor-type label comes from a closed list of three values; the code discards any other valueClosed category vocabulary (codebook)Krippendorff, "Content Analysis", 2004
One owner per datasetthe output is two files: audit.csv with 13 columns, and meta.json, the run passport: niche, date, method, sample size, spendingData passport (datasheet)Gebru et al., CACM, 2021
03 · Build

How it is built

The pipeline is linear and calls a paid service exactly twice: for company search and for site crawling. Everything else is our own code in one file, with requests as the only dependency.

Search returns 76 companies for 36 credits. Then comes the only manual step: a person strikes out aggregators, duplicates and off-niche companies by eye, and 76 becomes 30. Each site is opened in a real browser: the home page plus up to five inner pages, with links to prices, plans and price lists taken first; otherwise the top menu eats all five slots. In parallel, a free probe with a plain HTTP request records the status code and the load time in milliseconds.

The text goes to the model twice: "does the page answer the client's question", with a mandatory quote, and "what type of contractor is this", with a label from three values. Three code checks stand between the model's answer and a table row: the quote is not empty → the quote contains an amount or a timeline → the numbers from the quote are found on the page. Price, request form and calculator are detected by code from a dictionary, without the model.

All downloaded texts go into raw/: 155 pages, 52.2 MB in 58 files. So the dashboard, with its map of 24 attributes and the price distribution, is built from saved texts and spends no credits, and recalculating after a change to a check costs nothing.

COMPANY SEARCHFirecrawl · 36 credits6 queries, 30 results each → 76 companiesLIST CLEANUPperson76 → 30: aggregators, dupes, off-nicheSITE CRAWLFirecrawl · 139 creditshome + up to 5 inner pages, 6.5 s pauseCLIENT QUERYmodel“yes” only with exact quoteTHREE CODE CHECKScodequote → number in quote → number on pagepassedrejectedROW WITH QUOTE20 of 29 · to table“NO” + REASON9 of 29 · to logRAW/rerun: 0 creditsdashed: cache reuse · pink: manual step and the check that voids the model's “yes”
The model's answer never reaches the table on its own: three code checks stand between it and a row. This is where nine of the twenty-nine "yes" answers were overturned.

A code check always stands between the model's answer and a table row: a "yes" without a number found on the page itself never reaches the table.

04 · Rules

What holds the design together

Six rules, each stated against the alternative it rejects. In three of them the code does not trust the model; in the other three it does not trust itself.

All six can be checked against the run's artifacts in a minute: the quote column opens next to the site, the denominator is in the run passport, and the three check states are visible in the table itself.

1
Quote or noa "yes" without a verbatim quote is not written to the tableasked directly, the model agrees almost everywhere. The quote is the only part of its answer a person can recheck in a second by opening the page
2
Numbers, not wordingdigits from the quote are compared, not texta price on a site lives in a table, and the model retells it as a sentence, so a literal match would never work. An amount that is not on the page, though, cannot be found in any form
3
Denominatoronly sites that opened: 29, not 30a site closed to programs cannot be filed as "bad", because nothing is known about it. It counts in neither the numerator nor the denominator
4
Three states instead of twoyes, no, not checkedan empty cell is not a "no". A silent skip turns into a number with no measurement behind it, and nothing downstream can catch it
5
The reporting threshold is set before the run, not afterThe reporting threshold is set before the run, not afterone site in a sample of 29 weighs 3.4 percentage points: "68%" becomes "71%" although nothing has changed. Fewer than 40 sites opened means absolute numbers only; fewer than 25 means plan B
6
Code handles everything a person can recheck by handCode handles everything a person can recheck by handprice, form and calculator are found by a dictionary, not by the model. A person can repeat a code check in a second, but not a model's decision; of the thirteen table columns, the model fills three
05 · Decisions

Decisions and their grounds

Eight decisions, each backed by a measurement or a hard limit of an external service. None was made for tidiness: each either removes a specific error or stays within an external service's limit.

The decision with the biggest consequences is the pause between requests. On its own it stretches the run to forty-five minutes, and it has its own row in the limits section.

DecisionGrounds
Pages are opened by a rendering service, not a plain requesthalf of small-business sites render in the browser, and a plain request returns an empty shell. In the run this happened exactly once: one site of 29 returned text only when rendered and did not answer a direct request
A cap of 6 pages per site, pricing pages firstotherwise the top menu eats the five inner slots. The group order is fixed: prices, plans, price list → services → case studies and "about us"
No more than two pages from one sectionwithout this, all five slots go to one subsection and the rest of the site stays unread
A 6.5-second pause between crawler callsthe free plan allows 10 requests per minute. The slowness is deliberate: it is the price of the free plan, not slow code
The contractor-type label comes from a closed list of three valuesa free-form label cannot be counted: 29 sites would produce 29 wordings. The code silently discards any other value
Site texts are saved to raw/ and not downloaded againrecalculating after a change to a check costs zero credits. In the August 21 run, three sites came from the cache at 0 credits: 17 pages downloaded earlier
The dashboard is built from saved texts and does not download pages againthe map of 24 attributes and the price distribution cost 0 Firecrawl credits. The trade-off: 29 model calls that are missing from the run passport
The estimate is printed before the start, and spending is capped30 sites × up to 6 pages = up to 180 credits. The run used a cap of 220 against a default of 400; the cap was set by hand, and the run files do not record why it was 220. 139 were spent, 81 remained. The cap is checked before each site, not at the end
Sample attrition: from search hit to comparable price
Found by search7636 credits
After manual cleanup3039%
Opened2938%
With a starting price2128%
The second stage is the only manual step. After that, the code does the filtering.
06 · Limits

What the design costs

The main cost is time. The 6.5-second pause between requests stretches a run of 30 sites to about 45 minutes. That figure is not measured: it is reconstructed from the timestamps of the raw files. A sample of 50 sites at the same speed would take an hour, and that is a calculation, not a second run. Only a paid plan speeds this up. Of the total, 155 downloaded pages at 6.5 seconds each add up to about 17 minutes of pure waiting (155 × 6.5 s). Page rendering takes most of the rest; the model and text parsing barely add to the duration.

The second cost is strict definitions. Requiring a number in the quote cuts off sites that answer the client in words: at least one of the nine "no" answers in the run was given at exactly this step, and the reason is recorded in the log. The cap of six pages means that a price hidden on page seven does not make it into the measurement. On average, 5.3 pages were read per site.

Separately, the run's artifacts contain three price counters that give different numbers. This is not an error: they are three different definitions, and here they are in full. 27 of 29 in the report means "mentions a price": the page contains a word from the dictionary (the Russian for "plans", "price list", "cost of services", "% of the amount") or a number with a ruble sign. 25 of 29 in the dashboard means "price as a number": a regular expression only, matching a number with ₽ or a Russian abbreviation for rubles anywhere in the saved text. 21 of 29 in the price distribution is the starting monthly price for promotion: the number was named by the model or by a verified quote, and the code found it on the page, within a range of 3,000 to 3,000,000 RUB (about $35–35,000).

The difference in one sentence: the first two counters answer "is there a figure with a ruble sign on the page", while the third answers "can this figure be turned into a monthly price". The arithmetic checks out. Of the 25 sites with a number, five do not yield a monthly price (the number is the price of another service or a figure from a case study). One site is added back: it says "from 100,000", but its ruble sign is a letter drawn by an icon font, so the regex missed it while the model read it. 25 − 5 + 1 = 21.

The third counter has two sources, and they overlap. The model named a starting price in 13 profiles of 29, the verified quote gave one for 18 sites, and 10 sites are in both. So profile only: 3 sites; profile and quote: 10; quote only: 8; 3 + 10 + 8 = 21.

This page gives almost no percentages, and that is a cost too: 29 sites opened, fewer than forty, and under the project's method a sample below forty is reported in absolute numbers. Where a ratio such as "×10" or "+20%" appears, it is calculated from the sites' own price lists, not as a share of the sample.

DecisionWhat it limits
A 6.5-second pause between requestsa run of 30 sites takes about 45 minutes, judging by raw-file timestamps rather than a measurement; 50 sites at the same speed take over an hour, which is a calculation. Only a paid plan is faster: this is the free plan's limit of 10 requests per minute
A cap of 6 pages per sitea price on page seven does not make it into the measurement. 155 pages were read across 29 sites, 5.3 on average
The denominator counts only sites that openedthe figure measures availability to the crawler, not to a client. In the run, the only site that "did not open" was alive: the crawler got a timeout, while the direct probe opened the page in 1,402 ms
A "yes" requires a number in the quotea site that answers the client in words, without an amount or a timeline, ends up as a "no". Of the nine "no" answers, at least one was given at exactly this step
Price, form and calculator are found by a dictionaryit catches word forms, not meaning. "Price as a number" sees any number with a ruble sign (25 sites of 29), while a monthly price can be built for only 21
The contractor label has three values"freelancer-studio" went to one site of 29. A finer picture requires expanding the list and recalculating the whole run
The model does not always name a priceit gave a starting price in 13 profiles of 29; eight more sites got a price from the verified quote. Total: 21 of 29, and eight sites have no price at all
A sample below 40absolute numbers only until the end of the stage. One site weighs 3.4 percentage points, and percentages would suggest a precision the measurement does not have
07 · Result

What came out

sites opened during the crawl29 of 30out/meta.json: sample_listed 30, sample_opened 29
answered and backed it with a quote20 of 29out/audit.csv: answers_q1=True in 20 rows, quote not empty
Firecrawl spending per run175 credits139 crawl (out/meta.json) + 36 search (service diagram)
run durationabout 45 minnot measured: from file times in out/raw-*.tar.gz
Niche map: how many of the 29 sites say each of these things
Case studies27
Individual approach25
Comprehensive approach25
Price as a number25
Plans and packages23
Messengers23
Transparent reporting22
Contract with KPIs20
Case studies with numbers20
Industry specialization16
Certificates and awards16
Free audit15
Calculator13
Client dashboard10
Work under contract10
Personal manager9
Experience: years in business9
Guaranteed results7
White-hat methods5
Money-back5
Speed promise5
Free consultation3
Pay for results2
No prepayment0
At the top is what almost everyone says, so it sets nobody apart. Grey marks open ground. "No prepayment" did not appear once.
Price buckets: 21 sites that named a monthly price, thousand RUB
1under 25
1225–50
350–75
275–100
1100–125
2125–150
Columns start from zero. Median for the whole niche: 45 thousand RUB (about $525); SEO-only contractors 40, full-service agencies 48.

The run on August 21, 2026: niche "website promotion, Moscow", 30 sites on the list. 29 opened, and 20 answered the client's question and backed it with a quote. Spending: 175 Firecrawl credits out of 1,000 free per month. The 139 for crawling are in the run passport; the 36 for search come from the service diagram and were added during review. Duration: about 45 minutes, and that is not a measurement. It is reconstructed from the raw files' timestamps, 16:18 → 17:03, because the log has no timestamps at all.

The niche broke down into 24 attributes, and the distribution is a result in itself. Case studies appear on 27 sites of 29, case studies with numbers on 20: the other seven have no result of the form "+N%" or "N times" on the page, which is how this attribute is defined. 7 of 29 promise guaranteed results, while 2 of 29 back that with money ("pay for results"), so the promise is three and a half times more common than the commitment. Not one of the 29 sites offers to work without prepayment: it is the only attribute on the map that never appeared.

Prices could be extracted for 21 sites. The entry price is 15,000 RUB (about $175), the median 45,000 RUB (about $525), the top 150,000 RUB (about $1,750): a tenfold gap. The cheapest and the most expensive of the sites that named both a price and a timeline promise results in the same 3 months. The price differs tenfold; the promise is the same. The comparison rests on the eight sites that named both values, and it is a calculation from their own price lists, not a measurement of outcomes.

Full-service work costs 20% more than plain SEO: a median of 48,000 RUB (about $560) against 40,000 RUB (about $470) for SEO-only contractors, with 10 priced sites in the first group and 11 in the second. This is a ratio of two medians, not a share of the sample.

Reliability of the result
Sample
One niche, one run: 30 sites on the list, 29 opened, 21 with a starting price. Search returned 76 companies; the only manual step, removing aggregators and duplicates by eye, brought them down to 30.
Spread
The sample is below forty, so this page gives no percentages: one site weighs 1/29 ≈ 3.4 percentage points, and percentages would suggest a precision the measurement does not have. Where a ratio like "×10" appears, it is calculated from the sites' own price lists.
Checks
Three code checks stand between the model's answer and a table row: the quote is not empty → the quote contains an amount or a timeline → the numbers from the quote are found on the page. Nine of the twenty-nine "yes" answers were overturned at these checks. Agreement between the model and a human on a subsample was not measured.
Does not generalize
The numbers apply to the niche "website promotion, Moscow" as of August 21, 2026, and to what the crawler sees on six pages per site. A run on the niche named on the service card has not been done yet.
Not measured
Precision and recall of the attribute dictionary against manual labeling: the case of the ruble sign from an icon font shows that the dictionary makes errors, but their share is not counted. The run duration is reconstructed from file times, not measured.
Works

It passed a production run on August 21, 2026, on 30 sites in the niche and left verifiable artifacts: a 30-row table, the run passport, a dashboard and 52.2 MB of saved texts. The figures on this page can be recalculated from that archive; the two that cannot are named under "Pitfalls".

Repeat it yourself
Architectureflowchart above ↑Rulessix rules ↑Run dataaudit.csv, 30 rows

Kaufman Lab is an AI architecture lab. We design processes and methodologies. Code goes out of date with every new generation of models, but methodology does not, so methodology is what each project breaks down. Any current AI model can build a system from this design.

08 · Pitfalls

What went wrong

Ten failures, all found while reviewing the run's own artifacts, not during the build. Eight of the ten concern accounting: the recorded spending, time, search coverage and run passport do not match what actually happened. The other two are about definitions: a figure is labeled as something other than what it measures.

The one with the biggest consequences is the run passport. It declares the method as "firecrawl search + scrape → yandexgpt-lite", while the code uses a different model and a different provider. The file itself was rewritten on August 25, four days after the run, whereas the table and the log were written on August 21 at 17:03:58. A passport rewritten after the fact stops being a passport.

beforeafter139175

Credits in the run passportthe search step writes its cost to the passport

beforeafter5887

Model calls in the run totalthe dashboard records its own spending

The only site that "did not open" was alive: the crawler returned a timeout, while the direct probe opened it in 1,402 msThe figure is labeled "available to the crawler", not "site is down". Both columns, rendered and direct request, sit side by side in the table
A reason was recorded for only one of the nine "no" answers; the other eight went into the table unexplainedEvery "no" carries a reason. The branch that rejects silently is fixed; otherwise the decision cannot be reconstructed from the log
The reason note is printed before its site's line and reads in the log like a note on the previous siteThe event line is printed whole, with the reason as part of it, not as a separate line above
The run passport names a model that is not in the code, and it was rewritten four days after the runThe passport is written at measurement time and never edited afterwards. A mismatch between passport and code is a reason to stop, not to smooth it over
Of the six search queries, only three made it into the sample: 17 + 9 + 4 = 30 companies; the other three produced no rowsThe run passport states not only the sample size but also how many queries it was built from. Search coverage is part of the method, not a technical detail
36 search credits are missing from the passport: it says 139, while the run actually spent 175Spending includes everything the external service charged, search step included. A step that prints its cost to the console but does not pass it to the passport leaves that cost uncounted
139 credits is not the price of a cold run: three sites went through the cache for freeThe spending is shown together with the cost of a cold-cache run: here, 156 crawl credits
29 model calls from the dashboard are recorded nowhere: the run's total is 87, not 58Each component counts its own spending. The dashboard keeps its own tally instead of inheriting someone else's
The run log has no timestamps at all, neither start nor finishDuration is part of the run passport. Reconstructing it from file modification times is fine once; citing it as a measurement is not
Three price counters in the report and dashboard are labeled as if they measure the same thing: "Mentions a price" 27, "Price as a number" 25, the price chart 21A label names the definition, not the conclusion. "Mentions a price" measures whether a word like "plans" appears on the page, and the label must say exactly that
09 · Possibilities

What else can be added to the code

All downloaded texts live in raw/, and the dashboard is built from them without new credits, so a new attribute or a new report is one more pass over the archive, not a new crawl of the niche. Below is what can be added next, including paid services.

SpeedA paid crawler planThe 6.5-second pause is the limit of Firecrawl's free plan, not a property of the code. A paid plan removes it with one setting; the pipeline and the three checks stay the same. A run on a niche of 50 sites no longer waits on the pause.
ReviewsWhat competitors' clients complain aboutThe same crawler collects reviews of the niche's companies from Yandex Maps and 2GIS, Russia's main map and business directory services. The model lists what clients are unhappy about, only with a quote, and the code matches the quote against the review text. You see what the niche fails to give its clients, which is a ready argument for your own offer.
AdsWhich search queries competitors pay forPaid services such as Keys.so or SpyWords show which queries a company buys ads for in Yandex Direct, Yandex's ad platform, and which ads it runs. The export adds one row per company alongside audit.csv. Beside a site's promises, you see where the competitor actually puts its money.
CitiesOne niche in several citiesThe city is already set in the search string and recorded in the run passport. A run over a list of cities produces a separate table for each, and the dashboard combines them into one price map. You see where the entry price is lower and where the market has more room.
AccuracyManual labeling as a ruler for the dictionaryA person labels the attributes by hand on part of the sites, once. After that, every run prints how closely the dictionary and the model match this labeling. An error like the ruble sign from an icon font becomes a number, not a chance find.
OfferAn offer built on the niche's empty spotsThe model takes the map of 24 attributes and the price buckets and proposes offer wordings where the niche is silent. In our run, none of the 29 sites works without prepayment. The owner chooses; the model only shows the open space.
10 · Questions

What people usually ask

Ten questions people ask most often about this measurement. The first one defines the subject and is written to stand on its own when quoted out of context.

Every answer contains a number from the August 21, 2026 run or a published market price.

What is an AI competitor analyst?

An AI competitor analyst is a measurement in which a program, not a person with a notepad, crawls the websites of an entire niche. It is for business owners and marketers who need the whole market, not three well-known names. The program finds the sites, reads each one in a real browser and puts price, timeline and promises into a table. Kaufman Lab builds it for the client's niche: one run covers 30 sites. It does not rate the sites and does not give advice.

In competitor analysis, what does the model decide and what does the code decide?

The model answers one question, whether the page answers the client's main question, and must back a "yes" with a verbatim quote. Its second call assigns a contractor-type label from a closed list of three values; the code discards any other value. Price, request form, calculator and the 24 niche attributes come from text search without the model: a person can repeat such a check in a second, but not a model's decision. Of the thirteen table columns, the model fills three.

How do you check that a site actually answered the client's question?

With three code checks in a row, before anything is written to the table. The quote is not empty. The quote contains an amount or a timeline; otherwise the "yes" is overturned and the reason goes to the log. The numbers from the quote are found in the page text, and it is digits that are compared, not wording: a price on a site lives in a table, the model retells it as a sentence, and a literal match would never work. In the August 21, 2026 run, 20 of 29 sites passed all three checks, and each has its quote in a separate column.

Why is a site that did not open not counted as bad?

Nothing is known about it, and the denominator of all shares counts only the sites that opened: 29, not 30. In the August 21, 2026 run, the only site that "did not open" was in fact alive: the crawler returned a timeout, while a free direct probe from the same script got the page in 1,402 ms. That is why the figure is called "available to the crawler", not "site is down", and both columns sit side by side in the table.

Why does a run on thirty sites take about forty-five minutes?

Because of the 6.5-second pause between crawler calls: the free plan allows ten requests per minute. The run downloaded 155 pages, and waiting alone takes about 17 minutes. That is a calculation, 155 × 6.5 seconds, not a separate measurement; the rest goes to rendering the pages, while the model and text parsing barely add to the time. The 45 minutes are also reconstructed rather than measured, from the raw files' timestamps (16:18 → 17:03), because the run log has no timestamps. Only a paid plan makes it faster. The dashboard works from the texts already downloaded and does not download pages again.

How much does one run on a niche cost?

The August 21, 2026 run on 30 sites used 175 Firecrawl credits: 36 for company search and 139 for crawling. The free plan gives 1,000 credits a month and needs no card; the model in the current build runs on OpenRouter and adds no spending. On the market, the same work done by hand costs 26,000 RUB for three competitors, 53,000 RUB for five and 72,000 RUB for seven (about $300, $620 and $840), according to Demis Group's published price list. The code has no money figure for the run itself: it counts credits and calls.

What if only a few sites in the sample open?

The outcomes are declared before the start, not chosen after the result. Forty or more: percentages can be reported. From 25 to 39: the work goes on, but until the end of the stage only absolute numbers are used, since one site in a sample of 29 weighs 3.4 percentage points and "68%" becomes "71%" although nothing has changed. Fewer than 25: the fact that the niche is closed becomes the headline, and no percentages are published for the client question.

How do you analyze competitors' prices from their websites?

The program crawls the niche's sites in a real browser, the home page plus up to five inner pages, with links to prices and price lists taken first. Only the starting monthly price, found as a number on the page itself and falling between 3,000 and 3,000,000 RUB (about $35–35,000), goes into the price chart. In the August 21, 2026 run on the niche "website promotion, Moscow", this method produced a price for 21 of the 29 sites that opened: an entry price of 15,000 RUB (about $175), a median of 45,000 RUB (about $525), a top of 150,000 RUB (about $1,750), a tenfold gap. The numbers apply to one niche and one run.

How do you analyze the competitors of an entire niche?

Search collects the niche's companies; then comes the only manual step, where a person strikes out aggregators, duplicates and off-niche companies, and after that each site is read with the same set of checks. The method is ten steps from an empty folder to a project card. The funnel of the August 21, 2026 run: search returned 76 companies, 30 remained after cleanup, 29 opened. The model's answer to the client's main question is accepted only with a verbatim quote: the three checks overturned nine answers out of twenty-nine, and 20 passed.

What does a competitor analysis table look like?

It is a table with 13 columns and 30 rows: one row per company, with columns for price, timeline, promises, request form, calculator, availability and the verbatim quote. The model fills three of the thirteen columns; price, request form and calculator are found by code from a dictionary. A niche map of 24 attributes is built on top of the saved texts: in the August 21, 2026 run, 27 of 29 sites show case studies, 7 promise guaranteed results, and 2 offer pay for results.

Sources
  1. Nosek B. A., Ebersole C. R., DeHaven A. C., Mellor D. T. The preregistration revolution. PNAS, 115(11), 2018. doi:10.1073/pnas.1708274114
  2. Sharma M. et al. Towards Understanding Sycophancy in Language Models. 2023. arXiv:2310.13548
  3. Es S., James J., Espinosa-Anke L., Schockaert S. RAGAS: Automated Evaluation of Retrieval Augmented Generation. 2023. arXiv:2309.15217 — faithfulness: a claim can be inferred from the document.
  4. Krippendorff K. Content Analysis: An Introduction to Its Methodology. Sage, 2nd ed., 2004 — codebook, dictionary-based analysis.
  5. Codd E. F. Extending the Database Relational Model to Capture More Meaning. ACM Transactions on Database Systems, 4(4), 1979 — three-valued logic, missing values.
  6. Gebru T. et al. Datasheets for Datasets. Communications of the ACM, 64(12), 2021. doi:10.1145/3458723

Need a system like this?

Message me on Telegram: I answer myself, look at your task and tell you which of this fits it.

Message on Telegram→
More projects from the lab
↑ top