# Competitor Price Monitor — Wiser Alternative (`khadinakbar/wiser-alternative`) Actor

Monitor prices and availability on known competitor product pages. Export price, currency, source URL, timestamp, and same-currency gaps against your supplied price for a reviewable pricing snapshot.

- **URL**: https://apify.com/khadinakbar/wiser-alternative.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** E-commerce, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 validated price observations

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Competitor Price Monitor — Wiser Alternative

Monitor prices and availability on known competitor product pages. Export price, currency, source URL, timestamp, and same-currency gaps against your supplied price for a reviewable pricing snapshot. For pricing analysts, each dataset row is one accepted competitor product page with its observed price and comparison signal.

### Workflow: put the results to work

Supply product pages you have already checked for comparability. Add your price and currency to calculate a same-currency gap, then review price and availability together. The Actor observes pages; matching equivalent SKUs and deciding whether to change a price remain separate steps.

### Best fit

Use when a pricing analyst, retailer, or brand already has a short list of comparable public product URLs and needs a reproducible price snapshot for a spreadsheet, BI workflow, or internal review. Pair it with a source-specific catalog Actor for URL discovery, or choose a managed price-intelligence suite for automated matching, currency conversion, retained history, alert delivery, MAP enforcement, and repricing operations.

It returns public price, availability, product identifiers when present, source and canonical URLs, collection time, and an explicit comparison state. A row is billable only after both a public product title and a current price have been validated and written to the dataset.

Choose a dedicated marketplace Actor when you need a site-specific search, catalog, or reviews workflow. Choose Wiser when you need its managed matching, managed historical coverage, suite dashboards, reports, collaboration, MAP enforcement, or automated retail workflows.

### Input

`targets` is the only required field. Each object must contain one public product-detail URL. The caller, not the Actor, decides which URLs refer to comparable products.

```json
{
    "targets": [
        {
            "comparisonId": "wireless-headset-100",
            "retailer": "Example Retailer",
            "productUrl": "https://example.com/products/wireless-headset",
            "ownPrice": 100,
            "currency": "USD"
        }
    ],
    "alertThresholdPercent": 5,
    "maxConcurrency": 3,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": ["RESIDENTIAL"]
    }
}
```

`alertThresholdPercent` sets `alert: true` when a same-currency competitor is lower by at least that percentage of `ownPrice`. The Actor will not calculate a price difference when either currency is missing (`currency_unknown`) or when they differ (`currency_mismatch`).

### Output

Each dataset item is one current public product-page observation.

| Field                                         | Meaning                                                                                                           |
| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `competitorPrice`, `competitorCurrency`       | Current public price and currency when exposed by the page.                                                       |
| `originalPrice`, `availability`               | Public promotion and stock signals when exposed.                                                                  |
| `sku`, `gtin`, `brand`                        | Public product identifiers and brand when exposed.                                                                |
| `ownPrice`, `priceDelta`, `priceDeltaPercent` | Caller-provided own price and a calculation only for comparable currencies.                                       |
| `comparisonStatus`, `alert`                   | Explicit result of the price-gap rule; never an automatic repricing instruction.                                  |
| `matchStatus`                                 | Always states that the comparable URL was caller-supplied and unverified.                                         |
| `extractionMethod`, `retrievalMethod`         | Structured-data or metadata parser used, plus whether static HTML or the rendered-page fallback produced the row. |
| `sourceUrl`, `canonicalUrl`, `collectedAt`    | Evidence and freshness fields for review.                                                                         |

```json
{
    "comparisonId": "wireless-headset-100",
    "retailer": "Example Retailer",
    "productTitle": "Wireless Headset",
    "competitorPrice": 89.99,
    "competitorCurrency": "USD",
    "availability": "in_stock",
    "ownPrice": 100,
    "ownCurrency": "USD",
    "priceDelta": 10.01,
    "priceDeltaPercent": 10.01,
    "comparisonStatus": "competitor_lower_than_own",
    "alert": true,
    "matchStatus": "user_supplied_comparable_url_unverified",
    "sourceUrl": "https://example.com/products/wireless-headset",
    "collectedAt": "2026-09-07T12:00:00.000Z",
    "provenance": "public_product_page"
}
```

Every run also writes `OUTPUT` and `RUN_SUMMARY` in the default key-value store. Terminal outcomes are `COMPLETE`, `PARTIAL`, `VALID_EMPTY`, `INVALID_INPUT`, `UPSTREAM_FAILED`, or `CONFIG_ERROR`. A successful platform run alone is not evidence of useful data: inspect the dataset and these terminal records.

### A practical workflow

- Start with a reviewed list of public competitor product URLs for one SKU group.
- Attach your own price and ISO currency to each known comparison, then run the Actor.
- Filter the dataset for `alert: true`, open each source URL, and confirm the product match, variant, delivery conditions, and promotion before acting.
- Save the reviewed input as an Apify task, schedule it at the useful cadence, and send `OUTPUT` or filtered dataset results to your reporting or alerting workflow.

The Actor is read-only. It never changes prices, contacts retailers, opens accounts, purchases goods, or sends messages.

### API example

Use the Apify API with your own token; never place a token in a task example or shared dataset.

```bash
curl -X POST 'https://api.apify.com/v2/acts/khadinakbar~wiser-alternative/runs?token=YOUR_APIFY_TOKEN' \
  -H 'content-type: application/json' \
  -d '{
    "targets": [{
      "comparisonId": "wireless-headset-100",
      "productUrl": "https://example.com/products/wireless-headset",
      "ownPrice": 100,
      "currency": "USD"
    }],
    "alertThresholdPercent": 5
  }'
```

Retrieve the default dataset and the `OUTPUT` record from the execution response before you make a pricing decision.

### AI-agent / MCP prompt card

> For each provided public competitor product URL, return the latest validated price, currency, availability, source URL, collection time, and comparison status. Treat every match as unverified until the caller confirms the product identity, and keep commercial decisions behind human review.

An AI agent should inspect the dataset plus `OUTPUT` before continuing. `PARTIAL`, `VALID_EMPTY`, `INVALID_INPUT`, and `UPSTREAM_FAILED` are deliberate outcome signals; retry a corrected public URL or route a source-specific retailer to its dedicated workflow.

### Limits and recovery

Public product pages can vary by location, login state, selected variant, tax, shipping, inventory, and promotion. The Actor tries lightweight static HTML first, then uses a session-consistent rendered-page fallback when static retrieval yields an incomplete observation. It accepts a row when both title and price validate. For `PARTIAL` output, confirm the accepted source rows and retry the unresolved URLs with a lower concurrency setting. Keep login-gated, consent-gated, and private-account pages in an authorized workflow designed for that access mode.

### Builder's note

I built the acceptance rule around a practical lesson from testing retail pages: a request that returns HTML is still incomplete until both the product title and current price validate. That is why persistence and the observation charge happen together, while every accepted row keeps its source URL, collection time, extraction method, and retrieval method for review.

Every live dataset row carries its own `sourceUrl` and `collectedAt` value; the row is the evidence for the current public observation. Verify the source page and the private release records before using results commercially.

### How it compares with Wiser Solutions

This independent Actor is not affiliated, associated, sponsored, or endorsed by Wiser Solutions. Wiser’s public materials describe a broader price-intelligence offering with managed matching, monitoring, reports, alerts, and retail operations. The comparison below is limited to a short, caller-supplied public product-page snapshot.

| Decision dimension        | This Actor                                                                                                        | Wiser Solutions Price Intelligence                                                                                                     |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Scope                     | Reads a bounded list of public URLs and returns price observations.                                               | Broader pricing-intelligence workflows and managed operations.                                                                         |
| Billing and same-job cost | Pay per validated observation plus platform usage; inspect the live Pricing tab for current rates.               | Public materials direct buyers to a demo; this Actor makes no lower same-job cost claim without a comparable quote.                    |
| Effective efficiency      | A compact JSON dataset can be produced for each supplied page, but the caller still confirms product equivalence. | Managed matching and broader analysis can be the better fit when match quality and coverage matter more than a short URL-led snapshot. |
| Input friction            | Requires known comparable URLs and optional own-price context.                                                    | Wiser describes automated matching and custom workflows; it may reduce manual target preparation for an approved enterprise program.   |
| Output contract           | Exposes source URLs, collection times, nulls, and named terminal outcomes for downstream review.                  | Wiser describes flexible UI, reports, and integrated insight workflows.                                                                |
| Automation                | Read-only extraction; users may compose reviewed inputs with Apify tasks, schedules, APIs, and webhooks.          | Wiser describes real-time monitoring, alerts, and broader retail operations.                                                           |
| Freshness and provenance  | Each row carries its collection time and source URL; no historical continuity is implied by one run.              | Wiser describes configurable recurring monitoring and managed historical analysis.                                                     |

### Data-use boundary

For responsible use, collect only publicly accessible product information that you are authorized to access and collect. Respect retailer terms of service, robots guidance where applicable, local law, and your organization’s pricing and competition policies. Verify product identity, currency, tax, shipping, promotions, variants, availability, and MAP requirements before taking any commercial action.

### Pricing and run costs

This Actor uses **Pay per event plus Apify platform usage**. The [Pricing tab](https://apify.com/khadinakbar/wiser-alternative/pricing) lists the current event rates and billing terms.

| Event | Billing unit | When it applies |
|---|---|---|
| `apify-actor-start` | Actor Start | Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). |
| `price-observation` | Validated price observation | One public product page with a validated title and current price persisted to the dataset. Invalid pages and request failures are not charged as observations. |

Run cost combines the charged events and Apify platform usage. Review the run charge limit and requested result count before starting.

### Connect an AI agent

Use the [Apify MCP configurator](https://mcp.apify.com) to choose an available client connection. Inspect this Actor’s current input schema and required credentials before running it.

# Actor input Schema

## `targets` (type: `array`):

Provide 1–50 known public competitor product URLs. Each item may carry your product ID, own price, currency, and a retailer label. The URLs are treated as user-supplied comparisons, not automatically matched SKUs.

## `alertThresholdPercent` (type: `number`):

Mark a row alert=true when a competitor price is this percentage or more below ownPrice in the same currency. Default: 5.

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

Limits simultaneous public-page requests. Use a low value for sensitive retailers. Default: 3.

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

Optional Apify Proxy configuration for public product pages. Platform usage is billed separately.

## Actor input object example

```json
{
  "targets": [
    {
      "comparisonId": "nike-air-force-1",
      "retailer": "Nike",
      "productUrl": "https://www.nike.com/t/air-force-1-07-mens-shoes-WrLlWX/CW2288-111",
      "ownPrice": 130,
      "currency": "USD"
    }
  ],
  "alertThresholdPercent": 5,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `priceObservations` (type: `string`):

One validated public product-price observation per accepted URL.

## `compactOutput` (type: `string`):

Outcome, accepted count, rendered fallback telemetry, failure counts, and charged event counts.

## `runSummary` (type: `string`):

Detailed terminal diagnostics, retrieval-route telemetry, and public-data boundary.

# 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 = {
    "targets": [
        {
            "comparisonId": "nike-air-force-1",
            "retailer": "Nike",
            "productUrl": "https://www.nike.com/t/air-force-1-07-mens-shoes-WrLlWX/CW2288-111",
            "ownPrice": 130,
            "currency": "USD"
        }
    ],
    "alertThresholdPercent": 5,
    "maxConcurrency": 3,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/wiser-alternative").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 = {
    "targets": [{
            "comparisonId": "nike-air-force-1",
            "retailer": "Nike",
            "productUrl": "https://www.nike.com/t/air-force-1-07-mens-shoes-WrLlWX/CW2288-111",
            "ownPrice": 130,
            "currency": "USD",
        }],
    "alertThresholdPercent": 5,
    "maxConcurrency": 3,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/wiser-alternative").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 '{
  "targets": [
    {
      "comparisonId": "nike-air-force-1",
      "retailer": "Nike",
      "productUrl": "https://www.nike.com/t/air-force-1-07-mens-shoes-WrLlWX/CW2288-111",
      "ownPrice": 130,
      "currency": "USD"
    }
  ],
  "alertThresholdPercent": 5,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call khadinakbar/wiser-alternative --silent --output-dataset

```

## MCP server setup

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

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/Po3HLgDve1Lbf99Zw/builds/8Iexf7ixub5DfbGSv/openapi.json
