Use case · market intelligence

# Competitor price monitoring and market intelligence, as rows.

To watch a market you need three signals: what competitors charge, when that changes, and who ranks for your category. Crawl4AI Cloud gives each as data: `/price` reads pricing pages into plans and prices with the page quote behind each one, Watch tells you when a page changes in the way you describe, and `/serp` returns Google's results page as ranked rows.

Last checked 10 November 2026 · /price and Watch are in beta · prices from [GET /v1/prices](https://api.crawl4ai.com/v1/prices)

Do it now with your agent

## One prompt, and your agent builds it

Copy this, paste it into your coding agent (Claude Code, Cursor, Codex), add your API key, run it.

```text
Build a competitor pricing tracker with Crawl4AI Cloud.

GOAL
Each run: read my competitors' pricing pages into one table, compare it with the last run,
and write a short report of what changed. Optionally, set up alerts for price changes.

CRAWL4AI CLOUD
- Read the API reference for agents first: https://crawl4ai.com/llms.txt
- Base URL: https://api.crawl4ai.com
- Header on every call: Authorization: Bearer $CRAWL4AI_KEY
- My API key: YOUR_CRAWL4AI_API_KEY
  (no key yet: get a free key at https://crawl4ai.com/signin/)
- Put the key in the environment variable CRAWL4AI_KEY. Never write it into a file in the repository.
- Optional, use the MCP tools instead of HTTP (tools: price, watch_page, watch_changes):
  claude mcp add --transport http crawl4ai https://api.crawl4ai.com/mcp --header "Authorization: Bearer $CRAWL4AI_KEY"

INPUTS (ask me for any that are missing)
- COMPETITORS: domains or pricing page URLs, at most 20, for example ["hubspot.com", "semrush.com"]
- COUNTRY: two letters, the country whose visitors' prices I want, for example "us" or "gb"
- KEYWORD: optional, a search phrase for my category, for example "crm software pricing"

STEPS
1. Read the prices.
   POST /price  {"sites": COMPETITORS, "country": COUNTRY}
   Most calls answer in 10 to 60 seconds; set the HTTP timeout to 120 seconds.
   One row per site: provider, domain, status, url, currency, items[], add_ons[], discounts[], trial.
   status is ok, no_price, not_found, blocked or timeout. Keep the rows that are not ok in the report, with the reason.
   Each item: name, rank (1 = the cheapest paid plan), free, features[], limits[], and price:
   {amount, currency, period, billing, unit, usd, quote, change}. quote is the page text the price came from.
2. Save prices_YYYY-MM-DD.csv with the columns:
   domain, plan, amount, currency, period, billing, unit, usd, quote, pricing_url, read_at.
3. Find the changes.
   Compare with the newest earlier prices_*.csv: new plans, removed plans, changed amounts.
   Also report every item whose price.change is not null ({from, currency, at}: the price moved since the service last read it).
   For a longer view: GET /price/history?domain=DOMAIN&country=COUNTRY (1 credit).
4. Optional, Google ranks: GET /serp?q=KEYWORD&country=COUNTRY&num=10
   From results[] keep position, domain, title, url. Mark the rows whose domain is in COMPETITORS.
   blocks[] names what else Google showed (ai_overview, people_also_ask, ...).
5. Write report.md: one table per competitor (plan, price, period, USD), the cheapest paid plan of each,
   a "Changes since last run" list, the not-ok rows with their reason, and the Google table if step 4 ran.
6. Optional alerts. ASK ME FIRST: a monitor keeps checking and costs 1 credit per check and 3 per confirmed change.
   POST /monitors {"url": PRICING_URL, "watch": "a plan gets more expensive, a plan is removed, or a new plan appears",
                   "every": "auto", "agent": "pricing-bot"}
   Calling it again with the same url and watch returns the same monitor (created: false), so re-runs are safe.
   Read the changes: GET /monitors/changes?agent=pricing-bot (each has summary, facts[] with before/after, evidence links).
   Pause: PATCH /monitors/{id} {"paused": true}. Remove: DELETE /monitors/{id}. Save the ids to monitors.json.
7. Print the credits spent. /price costs 5 credits per site with a price, 1 when the page shows none,
   0 when blocked or timed out; the same call within 24 hours costs half. /serp costs 1 credit per Google page.

EXPECTED OUTPUT
prices_YYYY-MM-DD.csv, report.md, and monitors.json if step 6 ran.
Start with 3 competitors, show me report.md, then ask before adding the rest.
```

## How do I read competitor prices as data?

Give `/price` up to 20 domains or pricing page URLs. For a domain, it finds the pricing page. It returns every plan, tier, billing period, add-on, trial and discount the page shows, read as a visitor in the country you name. The example below is a real call for three sites as a visitor in the United Kingdom sees them.

```bash
curl https://api.crawl4ai.com/price \
  -H "Authorization: Bearer $CRAWL4AI_KEY" -H "Content-Type: application/json" \
  -d '{"sites":["hubspot.com","semrush.com","canva.com"],"country":"gb"}'
```

```json
{"recipe":"price","rows":[
 {"provider":"Hubspot","domain":"hubspot.com","country":"gb","status":"ok",
  "url":"https://www.hubspot.com/pricing","currency":"GBP",
  "items":[
   {"name":"Starter","rank":1,"free":false,
    "price":{"amount":7.0,"currency":"GBP","period":"month","billing":"monthly",
             "unit":"seat","usd":9.35,"quote":"£7/mo/seat","change":null},
    "features":["Everything in Free","Email and in-app chat support", ...],
    "limits":["Up to 10 users","5,000 credits/month"]}, ...]}, ...],
 "usage":{"units":8}}
```

Real answer, 10 November 2026, shortened to one plan of one site.

The same call put into a table:

| Site | Plan | Price on the page | USD |
|---|---|---|---|
| hubspot.com | Starter | £7/mo/seat | 9.35 |
| hubspot.com | Professional | £81/mo/seat | 108.24 |
| semrush.com | SEO | £95.07/mo | 127.04 |
| semrush.com | Starter | £133.84/mo | 178.84 |
| canva.com | Pro | £100 /year for one person | 133.62 |
| canva.com | Business | £180 /year per person | 240.52 |

From the call above, read as a visitor in the United Kingdom. Prices change; read them again before you use them.

Each price carries `quote`, the text on the page it came from. A price that is not on the page is never returned. When a price moved since we last read it, `change` holds the old value and the time. `GET /price/history?domain=hubspot.com&country=gb` lists every value we have read on a site.

## How do I get an alert when a competitor changes a price?

Watch (in beta) checks a page and tells you when it changes in the way you describe, in plain words. You get typed facts (what changed, from what, to what) and links to both versions of the page, by webhook, email or a feed your agent reads.

```bash
curl https://api.crawl4ai.com/monitors \
  -H "Authorization: Bearer $CRAWL4AI_KEY" -H "Content-Type: application/json" \
  -d '{"url":"https://competitor.com/pricing",
       "watch":"a plan gets more expensive, or a plan is removed",
       "every":"auto",
       "notify":{"webhook":"https://you.example/hook","secret":"s3cr3t"}}'
```

When the page changes, the event looks like this:

```json
{"event":"change","url":"https://competitor.com/pricing",
 "request":"a plan gets more expensive, or a plan is removed",
 "matched":["c1"],"confidence":0.97,
 "summary":"The Pro plan's price went from $49 / month to $59 / month.",
 "facts":[{"kind":"changed","entity":"Pro","field":"price",
           "before":"$49 / month","after":"$59 / month","section":"Pricing > Pro"}],
 "confirmed":true,"cost_credits":3}
```

Example from the [Watch docs](https://crawl4ai.com/docs/watch/), shortened. competitor.com is not a real customer.

A change is delivered 30 minutes after it was first seen, when the page has not gone back. With `every: "auto"` the page is checked as often as it really changes, at least once a day. A paused monitor keeps its history and costs nothing.

## How do I see who ranks on Google for my category?

`/serp` returns Google's results page as data: the true rank of each result, every block Google showed, and the place the page was localised to. A real call for "crm software pricing" as seen from the United Kingdom:

```bash
curl "https://api.crawl4ai.com/serp?q=crm+software+pricing&country=gb&num=10" \
  -H "Authorization: Bearer $CRAWL4AI_KEY"
```

```json
{"blocks":["ai_overview","organic","people_also_ask","related_searches"],
 "results":[
  {"position":1,"position_absolute":2,"domain":"expertmarket.com",
   "title":"How Much Does CRM Software Cost? Pricing Guide",
   "url":"https://www.expertmarket.com/uk/crm-systems/crm-software-cost"},
  {"position":2,"domain":"zoho.com","title":"Zoho CRM Pricing and Editions - Free for 3 users", ...},
  {"position":3,"domain":"pipedrive.com","title":"CRM Pricing Plans | Affordable CRM Software Costs", ...}, ...],
 "people_also_ask":["What is the average cost of a CRM software?","How much does a CRM cost?", ...],
 "pages":{"asked":1,"got":1,"missing":[]},"ms":1542}
```

Real answer, 10 November 2026, shortened.

`position` is the rank among the organic results. `position_absolute` counts every numbered item on the page, as a rank tracker does. Run the same query every week and you have a share-of-search table for your category.

## What about launches, reviews and other pages?

For any page without a ready call, `/extract` reads it and returns the fields you describe in plain words, checked against a JSON schema you give. For example: the plans on a page that /price does not read, the features on a changelog page, or the job titles on a careers page.

```bash
curl https://api.crawl4ai.com/extract \
  -H "Authorization: Bearer $CRAWL4AI_KEY" -H "Content-Type: application/json" \
  -d '{"url":"https://competitor.com/changelog",
       "instruction":"each release: its date, its title and the features it added",
       "schema":{"type":"array","items":{"type":"object","properties":{
         "date":{"type":"string"},"title":{"type":"string"},
         "features":{"type":"array","items":{"type":"string"}}},"required":["title"]}}}'
```

Ready-made scrapers for named sites (shops, review sites, launch sites) are on the [recipes page](https://crawl4ai.com/recipes/).

## What does market monitoring cost?

| Call | Credits | Note |
|---|---|---|
| /price, a site with prices | 5 | finding and reading the page is included; the same call within 24 hours costs half |
| /price, a site with no price shown | 1 | a blocked site or a timeout costs 0 |
| /price/history | 1 | every value read on a site, newest first |
| Watch, a check | 1 | once per interval; 2 when you set a fixed interval under 1 hour |
| Watch, a confirmed change | 3 | a change that matched your sentence |
| /serp, one Google page | 1 | up to 10 results; a page from our cache costs half |

From the /price and Watch docs and GET /v1/prices, read 10 November 2026. 1 credit = $0.001 at list price.

**Example, not a measurement:** 20 competitors read once a week (about 4 runs a month) is 20 × 5 × 4 = 400 credits. Watch on the same 20 pages, checked once a day (`every: "1d"`), is about 20 × 30 = 600 credits, plus 3 for each change. Together about 1,000 credits a month, which is the free plan's monthly credit. Starter is $10 a month for 10,000 credits. See [pricing](https://crawl4ai.com/pricing/).

## Can you run it for us?

Yes. On [Enterprise](https://crawl4ai.com/enterprise/) we design, build and run a pipeline for one job: competitor prices, launches and reviews across hundreds of sites, delivered as a daily table with changes flagged, to your warehouse, bucket, webhook or API. A dedicated fleet is quoted on your volume, billed yearly.

## Questions

### How often can I check a competitor's prices?

As often as you call /price. The same call within 24 hours comes from our cache at half price. For alerts, a Watch monitor checks the page as often as it really changes, at least once a day, or on a fixed interval from 4 minutes.

### Can I see the prices a visitor in another country sees?

Yes. Give `country` (two letters) or up to 5 `countries`. The page is read as a visitor there sees it, and each price comes back in that currency with a dollar value next to it.

### What if the pricing page has no prices, or the site blocks us?

The row says so in `status`: `no_price`, `not_found`, `blocked` or `timeout`. A site with no price costs 1 credit. A blocked site or a timeout costs nothing.

### Can the numbers be made up by the model?

Each price carries `quote`, the text on the page it was read from. A price that is not on the page is never returned.

### Can my agent read the changes?

Yes. `GET /monitors/changes` returns the new changes of all your monitors in one list, and the MCP server has the `watch_page` and `watch_changes` tools.

Next: [RAG and knowledge for LLMs](https://crawl4ai.com/use-cases/rag/) · [build vs buy](https://crawl4ai.com/build-vs-buy/) · [/price docs](https://crawl4ai.com/docs/price/) · [Watch docs](https://crawl4ai.com/docs/watch/) · [/serp docs](https://crawl4ai.com/docs/serp/)
