# Website Sales Trigger Radar (`nexascout/website-sales-trigger-radar`) Actor

Monitor business websites for booking-link failures, contact changes, technology changes, and website availability. Export evidence-backed sales triggers.

- **URL**: https://apify.com/nexascout/website-sales-trigger-radar.md
- **Developed by:** [NexaScout](https://apify.com/nexascout) (community)
- **Categories:** Business, Marketing, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 website sales triggers

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## 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

## Website Sales Trigger Radar

Monitor business websites for changes that can affect customer enquiries, bookings, and sales. The Actor compares each website with a saved baseline and exports structured triggers with evidence, verification status, and a suggested human check.

Use it for agency client monitoring, account research, and evidence-based sales follow-up. A trigger is an observation to investigate; it is not proof of lost revenue or purchase intent.

### What it monitors

- Booking and conversion links: added, removed, changed, broken, or recovered.
- Public contact details: phone numbers, email addresses, and contact-page changes.
- Website availability and recovery.
- Changes in detected booking, chat, ecommerce, and CMS technologies.
- Major homepage content changes.

The crawler uses HTTP checks with a bounded browser fallback. It can recognize links to external booking providers, but it does not complete bookings, submit forms, make purchases, log in, or solve CAPTCHAs.

### Quick start

1. Enter your website domains or URLs.
2. Set a memorable `historyKey` for this portfolio.
3. Run with `baselineMode: "AUTO"` and `saveHistory: true`.
4. Run again with the same websites and history key to compare.
5. Save a Task and attach an Apify schedule for ongoing monitoring.

The first run creates a baseline and normally produces **zero dataset items**. An unchanged repeat run can also produce zero items. Open **Output → Coverage, baseline and diagnostics** to see which websites were checked and whether any checks were inconclusive.

An initial automation block or inconclusive proxy failure does not create a baseline. Retry with AUTO: the first usable visit establishes a baseline without inventing website recovery or newly added buttons. Existing healthy baselines are preserved through these inconclusive visits.

```json
{
  "websites": [
    "https://www.rockawaydentalgroup.com/"
  ],
  "historyKey": "my-client-portfolio",
  "baselineMode": "AUTO",
  "saveHistory": true,
  "crawlMode": "CUSTOM_PATHS",
  "customCriticalPaths": ["/appointment-request/", "/contact/"],
  "maxPagesPerWebsite": 3,
  "maxDepth": 1,
  "maxConcurrency": 2,
  "pageTimeoutSecs": 15,
  "checkPerformance": false,
  "minimumSeverity": "LOW",
  "proxyConfiguration": {"useApifyProxy": true}
}
```

The sample business is a real website used for validation. Replace it with the websites you want to monitor.

### Choose a crawl

| Mode | Use |
| --- | --- |
| `HOMEPAGE_ONLY` | Small availability and homepage-content checks. |
| `CONVERSION_FOCUSED` | Discover relevant booking, contact, and conversion pages within your page/depth limits. |
| `CUSTOM_PATHS` | Prioritize known important pages using `customCriticalPaths`. These pages share the page budget with the homepage. |

Start with a small portfolio and 2–5 pages per website. Larger page limits, slow destinations, verification retries, browser fallback, and proxies can increase runtime and cost.

### Baselines and repeat monitoring

- **AUTO** creates a missing baseline and compares when one already exists.
- **FORCE_BASELINE** refreshes the baseline without emitting change triggers. Use deliberately when resetting your monitor.
- **COMPARE_ONLY** requires an existing usable baseline; inspect the run diagnostics if one is missing.

Keep the same `historyKey` for repeat runs. Use different keys for independent portfolios. Keep `saveHistory` enabled when you want the next run to compare against the latest saved observation.

Baselines persist in a named key-value store in the running account. Blocking and transport uncertainty preserve prior healthy information instead of creating artificial removal/recovery alerts.

### Results and coverage

**Default dataset:** one row per emitted trigger, including:

| Field | Meaning |
| --- | --- |
| `domain`, `website` | Website being monitored. |
| `triggerType`, `severity` | Type of change and its priority. |
| `status`, `verification` | How the finding was checked and how certain it is. |
| `title`, `summary` | Readable description. |
| `before`, `after`, `evidence` | Supporting observations, where applicable. |
| `salesReason` | Possible business relevance; human judgement is required. |
| `recommendedHumanCheck` | What to verify before acting on the finding. |
| `isNew`, `isResolved`, `occurrenceCount` | Issue lifecycle information. |

Export the dataset as JSON, CSV, or Excel using Apify's dataset export options. The **Sales triggers and verification** table presents the key columns.

**Output summary:** `OUTPUT` and `RUN_SUMMARY` records in the run's default key-value store contain processed/failed website counts, baseline counts, request metrics, per-website diagnostics, and warnings.

A platform run marked **SUCCEEDED** can still have summary status **PARTIAL**. For example, the homepage and contact page may load while an external booking provider blocks automated verification. Always review coverage, not just the platform run status.

### Interpret verification correctly

| Status | Interpretation |
| --- | --- |
| `CONFIRMED` | The specific check's evidence/recheck conditions were met. |
| `TARGET_LOADED` | The target page loaded. A booking, enquiry, or checkout was not completed. |
| `EXPECTED_FLOW_DETECTED` | A form or expected interface was detected. Successful submission was not tested. |
| `OBSERVED_ONLY` | A change was observed; investigate its business significance. |
| `INCONCLUSIVE_AUTOMATION_BLOCK` | Automation was blocked. This is not a confirmed broken booking or outage. |
| `INCONCLUSIVE` | Evidence was insufficient for a confirmed finding. |

Proxy/transport failures are also reported as uncertainty rather than proof that a business website is down.

### Ready-made monitoring Tasks

Five example configurations are available: booking links and CTAs, contact details, homepage availability/content, external booking providers, and an agency website portfolio. Each uses AUTO baselines, a separate history key, small crawl limits, and performance checks disabled.

These are configuration examples, not scheduled alerts. Change the websites and important paths before using a Task for your own clients. External provider monitoring includes an example that can return an automation block, demonstrating how partial coverage is reported.

### Optional performance checks

PageSpeed/Lighthouse comparisons require a `PAGESPEED_API_KEY` environment variable and `checkPerformance: true`. Without a configured key, no performance data is invented. These are lab measurements, not field Core Web Vitals; INP is unavailable from the lab response.

Performance checks were not part of the live-site validation described below. Leave them disabled unless you have configured and separately validated the provider.

### Validation and limitations

The monitoring implementation was checked on Rockaway Dental Group (New York), Rockaway Beach Dental Group (Pacifica, California), and Arverne Dental (New York), with baseline and repeat comparisons. Unit/integration checks covered verification and change/recovery cases.

On the tested Arverne booking link, Zocdoc returned HTTP 403. The Actor reported an inconclusive automation block and partial coverage, not a broken booking claim. A Neurality booking destination loaded, but a completed booking was not tested.

This is a bounded monitor, not a full-site crawl or end-to-end transaction test. Dynamic content, anti-bot protection, changing layouts, and unsupported technology signatures can reduce coverage. Dedicated pricing-page, service-page, and conversion-section change detection is not currently implemented.

### Pricing and automation

The live **Pricing** tab is the source of truth for current charges. Platform usage, proxy traffic, and any configured event fees can apply even when a run finds no changes.

Scheduling, webhooks, and downstream CRM/notification integrations are configured separately in Apify. The Actor exports observations; it does not send outreach or contact website owners.

# Changelog

This Actor's version history is a separate document: https://apify.com/nexascout/website-sales-trigger-radar/changelog.md

# Actor input Schema

## `websites` (type: `array`):

Business website URLs or domains to monitor (e.g. https://example.com).

## `maxWebsites` (type: `integer`):

Hard cap on the number of websites processed in a single run.

## `historyKey` (type: `string`):

Isolates independent baseline histories (e.g. 'agency-client-a'). Different keys never share baselines.

## `saveHistory` (type: `boolean`):

Persist a new baseline after each successfully scanned website.

## `baselineMode` (type: `string`):

AUTO = use prior baseline if present else create one; FORCE_BASELINE = overwrite baseline without emitting change triggers; COMPARE_ONLY = require an existing baseline.

## `crawlMode` (type: `string`):

HOMEPAGE_ONLY = homepage only; CONVERSION_FOCUSED = homepage + bounded conversion-relevant pages; CUSTOM_PATHS = homepage + customCriticalPaths.

## `maxPagesPerWebsite` (type: `integer`):

Bounded cap on pages crawled per website.

## `maxDepth` (type: `integer`):

Maximum link depth from the homepage. 0 crawls the homepage only (no conversion subpages).

## `pageTimeoutSecs` (type: `integer`):

Per-request HTTP timeout in seconds.

## `maxConcurrency` (type: `integer`):

Maximum concurrent website scans.

## `checkBookingAndCtas` (type: `boolean`):

Detect booking and contact calls to action and safely check their destination pages without submitting forms.

## `checkBrokenLinks` (type: `boolean`):

Report newly broken or recovered custom critical pages.

## `checkContactChanges` (type: `boolean`):

Compare public phone numbers, email addresses, and contact-page links with the previous baseline.

## `checkTechnologyChanges` (type: `boolean`):

Detect changes in visible website and booking-provider technologies.

## `checkPerformance` (type: `boolean`):

Optional PageSpeed (LAB) delta check. Score is 0..1; a material regression is rechecked before CONFIRMED. Requires PAGESPEED_API_KEY; otherwise reported unavailable.

## `checkAvailability` (type: `boolean`):

Report website availability changes and rechecked outages.

## `checkMajorContentChanges` (type: `boolean`):

Report material changes to conversion-related content while suppressing routine dynamic content.

## `verifyCriticalIssues` (type: `boolean`):

Recheck high-severity failures once before marking them confirmed.

## `recheckFailures` (type: `boolean`):

Repeat a failed request once before reporting a confirmed issue.

## `performanceDevice` (type: `string`):

Choose the mobile or desktop Lighthouse measurement profile.

## `ctaKeywords` (type: `array`):

Keywords used to detect conversion CTAs.

## `customCriticalPaths` (type: `array`):

Additional relative/absolute paths to inspect and recheck as independent critical pages (e.g. /booking). Emits CRITICAL_PAGE_BROKEN / CRITICAL_PAGE_RECOVERED.

## `emitUnchanged` (type: `boolean`):

When true, also emit a row for websites with no triggers.

## `minimumSeverity` (type: `string`):

Only emit triggers at or above this severity.

## `debug` (type: `boolean`):

Include additional diagnostics useful for investigating a run.

## `proxyConfiguration` (type: `object`):

Apify proxy configuration. When useApifyProxy is true (default), HTTP requests are routed through the Apify proxy.

## Actor input object example

```json
{
  "websites": [
    "https://example.com"
  ],
  "maxWebsites": 100,
  "historyKey": "default",
  "saveHistory": true,
  "baselineMode": "AUTO",
  "crawlMode": "CONVERSION_FOCUSED",
  "maxPagesPerWebsite": 12,
  "maxDepth": 2,
  "pageTimeoutSecs": 25,
  "maxConcurrency": 5,
  "checkBookingAndCtas": true,
  "checkBrokenLinks": true,
  "checkContactChanges": true,
  "checkTechnologyChanges": true,
  "checkPerformance": true,
  "checkAvailability": true,
  "checkMajorContentChanges": true,
  "verifyCriticalIssues": true,
  "recheckFailures": true,
  "performanceDevice": "MOBILE",
  "ctaKeywords": [
    "book",
    "book now",
    "schedule",
    "schedule now",
    "reserve",
    "reservation",
    "appointment",
    "get quote",
    "request quote",
    "contact",
    "call now",
    "order",
    "buy",
    "sign up",
    "free consultation"
  ],
  "customCriticalPaths": [],
  "emitUnchanged": false,
  "minimumSeverity": "LOW",
  "debug": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `triggers` (type: `string`):

No description

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

No description

# 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 = {
    "websites": [
        "https://example.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("nexascout/website-sales-trigger-radar").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 = { "websites": ["https://example.com"] }

# Run the Actor and wait for it to finish
run = client.actor("nexascout/website-sales-trigger-radar").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 '{
  "websites": [
    "https://example.com"
  ]
}' |
apify call nexascout/website-sales-trigger-radar --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nexascout/website-sales-trigger-radar"
        }
    }
}
```

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/MLxzfIKdRIFP6NOte/builds/k1OyBSnyyFgRzf6uj/openapi.json
