# Competitor Price Monitoring API - Matched SKU Prices, Stock (`nabeelbaghoor/competitor-price-monitoring-api`) Actor

Competitor price monitoring for your matched SKUs: every store's price, regular price, previous price, savings, promotions, shipping and stock, per SKU lookups and on-demand live prices from the Wiser Price Intelligence API. Read only. Bring your own key.

- **URL**: https://apify.com/nabeelbaghoor/competitor-price-monitoring-api.md
- **Developed by:** [Nabeel Hassan](https://apify.com/nabeelbaghoor) (community)
- **Categories:** E-commerce, Business, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$8.00 / 1,000 competitor price listing returneds

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

## Competitor Price Monitoring API - Matched SKU Prices, Stock

Pull every competitor price your price intelligence account tracks into a clean dataset: one row per store listing matched to one of your SKUs, with price, regular price, promotions, shipping and stock.

### What it collects

- **All matched SKUs**: every SKU in your catalog environment with every competitor listing matched to it, page by page, up to 1,000 SKUs per page. Each row carries the store name, marketplace seller, listing URL, match type (exact or equivalent), price, regular (strike-through) price, previous price, savings, savings message, special offer, shipping price and shipping message, in-cart pricing flag, stock and crawl time, beside your SKU code, title and level 1 and level 2 categories.
- **Competitor listings for a SKU**: the same listings for each SKU code you give, with the SKU's UPC, model number, title and image.
- **Live competitor price**: an on-demand, real-time price, shipping price and stock for each competitor product id you give, fetched from the product page itself.
- **Filters**: listings crawled within the last N hours (sent to the provider), and store, match type and in-stock filters applied to the answer.
- A computed discount percentage from price and regular price on every row.

### Input

| Field | What it does |
| --- | --- |
| What to read | All matched SKUs (default, needs nothing else), competitor listings for a SKU, or live competitor price. |
| SKUs or competitor product ids | One per line. SKU codes for the SKU lookup, competitor product ids (the productId column) for live prices. |
| Crawled within the last hours | All matched SKUs only: keep listings crawled in the last N hours. |
| Start page | All matched SKUs only: the page to start from. |
| Match type | Any, exact only or equivalent only. |
| Only these stores | Store names to keep, one per line. |
| In stock only | Keep only listings seen in stock. |
| Maximum results | Row cap for the run. |
| Requests per minute | Pacing, up to the provider's 200 per minute. |
| API key | Your own key, as a secret input. |

### FAQ

#### What is a competitor price monitoring API used for?

Feeding competitor prices into the systems that act on them. A pricing team loads every matched SKU into its data warehouse each morning with a 24 hour crawl recency filter and computes its price gap per store. A rule-based repricing engine reads live prices for its fastest-moving SKUs during a promotion. A brand checks resellers for minimum advertised price and stock across Walmart, Target, Best Buy and Amazon marketplace sellers. A merchant validates a new competitor match by looking up one SKU and opening each listing URL.

#### Which data source does this actor read?

The Wiser Price Intelligence API, through three read routes the provider documents in its public help centre: the Bulk Product API (`/api/v1/products`), the Product API (`/api/v1/product/sku/{sku}`) and the Live Prices API (`/api/v1/live/{product_id}`). It reads the SKUs and competitor matches already configured in your own account; it does not discover new competitors or add matches.

#### Do I need an API key?

Yes. This actor is bring-your-own-key and never ships one. Keys are issued by your account manager, one per catalog environment, with a rate limit of 200 requests per minute and a monthly usage cap per key. Paste the key into the input or set it once as the `DATA_API_KEY` environment secret. A missing key, a refused key or a used-up usage limit ends the run cleanly with a message saying which it was.

#### What is the difference between the three services?

All matched SKUs is the bulk feed: every SKU and every listing, read from the provider's latest scheduled crawl, which is the cheapest way to get the whole market. Competitor listings for a SKU is the same data for a short list of SKU codes. Live competitor price triggers a real-time extraction of one competitor product page per id; the provider caches each live price for one hour, and a page it cannot read comes back as an uncharged row with a note.

#### What happens when there is nothing for a SKU or id?

It becomes its own row with `found: false` and a note: a SKU with no active competitor matches, a SKU code the environment does not know, an unknown competitor product id, or a live page the provider could not read. Those rows are never charged.

#### Can this actor change anything in my account?

No. Every route it calls is a GET. The provider's webhooks and catalog uploads are not wired anywhere in this actor. The bulk route's pagination link contains your key, so it is never followed or stored; pages are requested by number instead, and the key never appears in a row or in the log.

#### How is it priced?

Pay per result: one flat price per competitor listing returned. Rows for SKUs or ids that produced nothing, and listings dropped by your filters, are free. Your provider account's own usage limits apply separately.

### Example output

```json
{
  "service": "bulkProducts",
  "serviceLabel": "All matched SKUs",
  "requested": null,
  "page": 1,
  "found": true,
  "sku": "TV-55-4K-01",
  "skuTitle": "55 inch 4K UHD Smart TV",
  "masterId": "a1b2c3d4",
  "environment": "us-electronics",
  "categoryLevel1": "Electronics",
  "categoryLevel2": "Televisions",
  "productId": "9f8e7d6c5b",
  "storeName": "Best Buy",
  "marketplaceSeller": null,
  "url": "https://www.bestbuy.com/site/example-55-tv/1234567.p",
  "matchType": "exact",
  "price": 449.99,
  "regularPrice": 529.99,
  "previousPrice": 499.99,
  "savings": 80,
  "discountPercent": 15.09,
  "savingsMessage": "Save $80",
  "specialOffer": null,
  "shippingPrice": 0,
  "shippingMessage": "Get it tomorrow",
  "inCart": false,
  "availability": true,
  "crawlDate": "2026-09-26 06:12:40",
  "retrievedAt": "2026-09-26T09:14:52.118Z",
  "note": null
}
```

Values are illustrative; every field is one the provider documents.

### Keyword map

competitor price monitoring API, competitor price tracking, price intelligence API, retail price intelligence, ecommerce pricing data, competitive pricing feed, price gap analysis, MAP monitoring, live competitor prices, real-time price API, SKU price lookup, matched products API, promotion tracking, shipping price monitoring, stock availability tracking, repricing data feed, Wiser Price Intelligence API.

# Actor input Schema

## `service` (type: `string`):

One service per run. All matched SKUs pages through every SKU in the catalog environment your key belongs to, with every competitor listing matched to it, and needs no identifiers, so it is the default. Competitor listings for a SKU reads the listings for each SKU code you give. Live competitor price asks the provider to fetch the current price of each competitor product id you give, from the product page itself, which is slower and cached by the provider for one hour.

## `identifiers` (type: `array`):

One per line. For competitor listings for a SKU, your own SKU codes as they appear in your catalog. For live competitor price, the competitor product id, which is the productId column of any row this actor returns. All matched SKUs reads none.

## `crawlRecencyHours` (type: `integer`):

All matched SKUs only. Return only competitor listings the provider crawled within this many hours, for example 24 for a daily feed. Left blank, every active listing is returned.

## `startPage` (type: `integer`):

All matched SKUs only. The page to start from. Each page holds up to 1,000 of your SKUs with all their listings, and the actor keeps reading later pages until the last one or the maximum results.

## `matchType` (type: `string`):

All matched SKUs only, because only that route reports it. Exact keeps listings of the identical product; equivalent keeps comparable products the provider matched as equivalents. Applied by this actor to the provider's answer.

## `storeNames` (type: `array`):

Keep only listings from these stores, one store name per line, written as the provider names it in the storeName column. Case does not matter. Applied by this actor to the provider's answer; left empty, every store is kept.

## `inStockOnly` (type: `boolean`):

Keep only listings the provider saw in stock. Applied by this actor to the provider's answer.

## `maxResults` (type: `integer`):

Stop after this many rows. One page of all matched SKUs can hold thousands of listings, so this is what bounds a run and its cost.

## `requestsPerMinute` (type: `integer`):

Pacing ceiling. The provider allows 200 requests per minute per key and also caps monthly usage per key, so the default sits at half the per-minute limit to leave room for anything else using the same key.

## `apiKey` (type: `string`):

Your own price intelligence API key, which your account manager issues per catalog environment. This actor is bring-your-own-key and never ships a key of its own. Leave blank to use the DATA\_API\_KEY environment secret instead. The provider documents the key as a query parameter only, so that is how it travels, and no request URL is ever logged or stored.

## `baseUrl` (type: `string`):

Override the host the actor calls. Only useful for testing against a different environment.

## Actor input object example

```json
{
  "service": "bulkProducts",
  "matchType": "any",
  "inStockOnly": false,
  "maxResults": 1000,
  "requestsPerMinute": 100
}
```

# Actor output Schema

## `listings` (type: `string`):

One row per competitor listing, alongside the SKU or product id that produced it.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("nabeelbaghoor/competitor-price-monitoring-api").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("nabeelbaghoor/competitor-price-monitoring-api").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 '{}' |
apify call nabeelbaghoor/competitor-price-monitoring-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nabeelbaghoor/competitor-price-monitoring-api"
        }
    }
}
```

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/1hW1DfGpCzIqdqxwE/builds/QFpz86mHRhlTirrpu/openapi.json
