# Competitor Page Change Monitor (`nexuslead/nexus-intelligence`) Actor

Type a competitor's website and get alerts on what changed on their pricing, plans and services pages, with source evidence. Reads JavaScript-built pages too.

- **URL**: https://apify.com/nexuslead/nexus-intelligence.md
- **Developed by:** [Justin Lopez](https://apify.com/nexuslead) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Competitor Page Change Monitor

Know when a competitor changes their pricing, plans or services. **Type their website. That's it.** The Actor finds the pages that matter, remembers them, and on every later run tells you **what was added and what was removed**, with the source URL and a timestamp as evidence.

No account elsewhere, no dashboard to sign up for, no code. Run it by hand, on a schedule, or from the API or an AI agent. It reads pages built with JavaScript too.

### What you get

- **Pages found for you**: give it `acme.com`, it finds their pricing, plans and services pages
- **Changed / unchanged / first-seen** status for every page
- **Added and removed passages** (up to 8 each, so you read the change, not the whole page)
- **Price strings spotted on the page** (for example `$39/month`), copied exactly as written
- **A plain-language summary of every change**, like "Prices: no longer shows $29; now shows $39. 3 passages added, 1 removed."
- **Price movement**: which price strings appeared and which disappeared since last time
- **Page type** (pricing, services, features or other) and full counts of added and removed passages
- **Evidence on every row**: requested URL, final URL, capture time, previous capture time, page title, content hash, how the page was read
- **A run summary** listing which URLs changed and which competitors had no page found
- **Honest gaps**: if a page can't be read, you get a failed row saying why. Failed pages are never charged and never overwrite your saved copy.

### How to use it

1. Type your competitors' websites (`acme.com`, `rival.io`) and run it once. Every page found is saved as a **baseline**.
2. Run it again later, or put it on a schedule (daily or weekly works well). Changed pages show what moved.
3. Use Apify's schedules, webhooks and integrations to send results to Slack, email, Google Sheets, Zapier or your own tools.

Your saved pages live in a private storage in **your own Apify account**. Nothing is shared with other users.

#### Input

```json
{
  "competitors": ["acme.com", "rival.io"],
  "pagesPerCompetitor": 3,
  "urls": [],
  "renderMode": "auto"
}
```

| Field | What it does |
|---|---|
| `competitors` | Up to 20 competitor websites. The Actor finds their pricing, plans and services pages from the homepage links and sitemap. |
| `pagesPerCompetitor` | How many of the best matches to watch per website (1 to 5, default 3). |
| `urls` | Optional exact page addresses (up to 50), watched first. Use it for pages the finder misses. |
| `maxPages` | Hard cap on pages per run in total (default 10, max 50). |
| `renderMode` | `auto` (default): read the HTML, switch to a real browser only if a page needs one. `html`: never use a browser. `browser`: always use one. |
| `rememberBaselines` | Save each page for next time (default on). Turn off for a one-off run. |
| `baselineStoreName` | Name of the storage that holds saved pages. Use different names for separate watchlists. |
| `includeText` | Include the page text in each output row (max 24,000 characters). |
| `previousResults` | Optional. Compare against rows from an earlier run instead of the saved pages. |

#### Output (one row per page)

```json
{
  "schemaVersion": 1,
  "competitor": "acme.com",
  "discoveredFrom": "link",
  "requestedUrl": "https://acme.com/pricing",
  "url": "https://acme.com/pricing",
  "status": "captured",
  "comparison": "changed",
  "captureMethod": "browser",
  "title": "Pricing",
  "capturedAt": "2026-10-22T16:00:00.000Z",
  "previousCapturedAt": "2026-10-21T16:00:00.000Z",
  "pageType": "pricing",
  "observedAmounts": ["$39/month"],
  "priceChanges": { "added": ["$39"], "removed": ["$29"] },
  "changeCounts": { "added": 1, "removed": 1 },
  "changeSummary": "Prices: no longer shows $29; now shows $39. 1 passage added, 1 removed.",
  "added": ["Starter $39 per month"],
  "removed": ["Starter $29 per month"],
  "error": null
}
```

`comparison` is `baseline` (first time seen), `changed`, `unchanged`, or `unavailable` (the page could not be read). `discoveredFrom` is `link`, `sitemap` or `guess` for found pages; it is absent for pages you listed yourself.

If you switch `renderMode` and a page is read a different way than last time, the Actor starts a fresh baseline for it (`baselineReset: true`) instead of reporting fake changes.

A `SUMMARY` record in the run's key-value store lists counts, every change with its plain-language summary, a per-competitor rollup, pages that failed, and competitors with no page found. Those competitors also get a free row telling you to add their page address.

### Pricing

You pay per page successfully read:

- `page-result`: a page read from its HTML.
- `browser-page-result`: a page that needed a real browser (it uses more compute, so it costs more).

First-seen, changed and unchanged pages each count as one result. Pages that fail and competitors with no page found are not charged. Set a maximum cost per run and the Actor stops when it is reached; results gathered so far are kept. Platform pricing is shown on this Actor's page.

### Good to know

- **Page finding is a best guess.** It looks for pricing, plans, packages, services and similar pages on the same website. Check the first run's results and add exact addresses in `urls` for anything it missed or got wrong.
- **Browser reading handles JavaScript, not logins.** Pages behind a login, a CAPTCHA, or heavy bot protection can still fail. You'll see a failed row, not a wrong answer.
- **Small wording changes show up.** It compares text, so a changed headline appears as a change. It does not judge whether a change matters.
- **Observed prices are strings, not facts about plans.** `$39` means that text appeared on the page.
- **Public pages only.** HTTPS on the standard port, no logins, no cookies, no private networks.
- **Be a good citizen.** Only monitor pages you are allowed to read, at a reasonable frequency, and follow each website's terms.
- A page that times out or returns a temporary server error is retried once.

### FAQ

**Do I need to paste page addresses?** No. Type the competitor's website and the Actor finds the pages. Exact addresses are optional.

**Do I need to paste old results each time?** No. Saved pages are used automatically. `previousResults` is only for overriding them.

**Where is my data stored?** In a key-value storage in your own Apify account, named by `baselineStoreName`. Delete that storage to reset.

**Can I watch more than 50 pages?** Run several watchlists, each with its own `baselineStoreName`, on separate schedules.

**Does it explain why a change matters?** Not yet. It reports the evidence; interpretation is up to you or your AI agent.

### Roadmap

Screenshots, public ad libraries, and AI summaries of changes are planned as later versions. Tell us what you need in the Issues tab.

# Actor input Schema

## `competitors` (type: `array`):

Just type each competitor's website, like acme.com. The Actor finds their pricing, plans and services pages for you (from the homepage links and sitemap) and watches those. Up to 20 websites. Combine with the page list below if you like.

## `pagesPerCompetitor` (type: `integer`):

How many of the best-matching pages to watch on each competitor website.

## `urls` (type: `array`):

Optional. Exact public HTTPS pages to watch. Use this when you already know the page, or for pages the finder misses. These are watched first. Duplicates are captured once.

## `maxPages` (type: `integer`):

Hard cap on pages per run in total (exact pages plus found pages), after deduplication. Successful captures count as results even if the text is unchanged.

## `renderMode` (type: `string`):

Auto reads the page's HTML first and switches to a real browser only when a page needs JavaScript or looks blocked. HTML only is fastest and cheapest. Browser always uses a real browser (slower, billed as a browser result).

## `includeText` (type: `boolean`):

Include the captured page text in each output row (at most 24,000 characters). Saved baselines always keep the text in your own storage regardless of this setting.

## `previousResults` (type: `array`):

Optional. Paste captured rows from an earlier run to compare against them instead of the saved baselines. Rows must be successful captures that include text, requestedUrl, url and capturedAt.

## `rememberBaselines` (type: `boolean`):

Saves the latest successful capture of each URL in a private storage in your own Apify account, so the next run shows what changed with no copy-pasting. Turn off for a stateless run.

## `baselineStoreName` (type: `string`):

Name of the key-value store in your account that holds saved pages. Use a different name to keep separate watchlists. 3-63 lowercase letters, numbers and hyphens.

## Actor input object example

```json
{
  "pagesPerCompetitor": 3,
  "urls": [
    "https://www.iana.org/help/example-domains"
  ],
  "maxPages": 10,
  "renderMode": "auto",
  "includeText": true,
  "previousResults": [],
  "rememberBaselines": true,
  "baselineStoreName": "nexus-intelligence-baselines"
}
```

# Actor output Schema

## `report` (type: `string`):

A one-page report: what changed, price movement and pages that could not be read.

## `pages` (type: `string`):

One row per page: changed, unchanged or first seen, with added and removed passages and prices spotted.

## `summary` (type: `string`):

Counts, every change with a plain-language summary, and competitors with no page found.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        "https://www.iana.org/help/example-domains"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("nexuslead/nexus-intelligence").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "urls": ["https://www.iana.org/help/example-domains"] }

# Run the Actor and wait for it to finish
run = client.actor("nexuslead/nexus-intelligence").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    "https://www.iana.org/help/example-domains"
  ]
}' |
apify call nexuslead/nexus-intelligence --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nexuslead/nexus-intelligence"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/c73SUMdhBeBt20Ixu/builds/wsYMlMOOtNdNbNQl9/openapi.json
