# Multi-Store Stock Alert (`arched_friend/multi-store-stock-alert`) Actor

Watch the same product across Amazon, eBay and any Shopify storefront in one run. Normalises every source into one feed, names the cheapest place to buy right now, and alerts you when a target price is met or something comes back in stock.

- **URL**: https://apify.com/arched\_friend/multi-store-stock-alert.md
- **Developed by:** [Peach O](https://apify.com/arched_friend) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$50.00 / 1,000 source checkeds

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

## Multi-Store Stock Alert: One Feed for Amazon, eBay and Shopify

Watch the same product across Amazon, eBay and any Shopify storefront in a single run. Every source comes back in one normalised shape, the cheapest place to buy right now is named, and you get an alert when your target price is met or something comes back in stock.

Built for buyers, resellers and sourcing teams who currently keep three tabs open and compare by eye.

### How it works

```mermaid
flowchart TD
    A["Your product: ASINs,<br/>eBay terms, Shopify stores"] --> B["Amazon Price Tracker"]
    A --> C["eBay Price Tracker"]
    A --> D["Shopify Price Tracker"]
    B --> E["Normalise to one shape"]
    C --> E
    D --> E
    E --> F["Scope to the tracked product<br/>by title"]
    F --> G{"Compare"}
    G --> H["Cheapest source"]
    G --> I["Target price met"]
    G --> J["Back in stock"]
```

This Actor does no scraping itself. It chains the three source Actors, so each store is read by the Actor that specialises in it, and a store that fails does not take the run down: you still hear about Amazon on a morning when eBay is throwing challenges.

### Built for

- **Resellers and arbitrage buyers** who need the cheapest source, not three tabs
- **Procurement and sourcing** benchmarking one part across marketplaces
- **Collectors** waiting for any store to hit a number
- **Brand owners** watching where their product is being sold and at what price

### Input

```json
{
  "productLabel": "insulated travel mug",
  "amazonAsins": ["B0FGJF172R", "B0FGJCYQKK"],
  "amazonMarketplace": "US",
  "ebayKeywords": ["zojirushi travel mug"],
  "ebaySite": "US",
  "titleMustContain": ["mug"],
  "targetPrice": 30
}
```

| Setting | What it does |
| --- | --- |
| `amazonAsins` | ASINs to price. Leave empty to skip Amazon |
| `ebayKeywords` | eBay searches to run. Leave empty to skip eBay |
| `shopifyStores` | Shopify storefronts to read. Leave empty to skip Shopify |
| `titleMustContain` | Scopes every source to the product you are actually tracking |
| `targetPrice` | Alerts when any in-stock offer hits this price or lower |
| `onlyAlerts` | Return only drops, stock flips and new listings |

**Set `titleMustContain` whenever you include a Shopify store.** A storefront returns its whole catalogue, and without a title scope the comparison will happily name an unrelated product as your cheapest offer.

### Output

```json
{
  "source": "ebay",
  "sourceLabel": "eBay",
  "group": "insulated travel mug",
  "key": "ebay:307065683170",
  "title": "Zojirushi SM-KHE48 Stainless Steel Travel Mug 16oz",
  "price": 26.23,
  "currency": "$",
  "inStock": true,
  "seller": "thriftbooks_us",
  "changeType": "new-listing",
  "isCheapest": true,
  "url": "https://www.ebay.com/itm/307065683170",
  "checkedAt": "2026-09-15T18:40:35.008Z"
}
```

The run summary names the winner and how each source fared:

```json
{
  "cheapest": { "source": "ebay", "price": 26.23, "url": "https://www.ebay.com/itm/307065683170" },
  "cheapestPerSource": {
    "amazon": { "price": 28.99 },
    "ebay": { "price": 26.23 }
  },
  "targetMet": { "source": "ebay", "price": 26.23 },
  "comparableCurrencies": true
}
```

### Prices are compared like for like

- **eBay prices include postage.** A £0.99 listing with £12 postage is compared at £12.99, which is what you would actually pay.
- **Out-of-stock offers never win.** The cheapest thing you cannot buy is not a useful answer, so unavailable rows are excluded from the comparison rather than ranked.
- **Mixed currencies are flagged, not silently ranked.** Pricing Amazon UK against eBay US would compare pounds with dollars and name the wrong winner, so `comparableCurrencies` comes back false and the run warns you.

### Run it as an API

```bash
curl -X POST "https://api.apify.com/v2/acts/arched_friend~multi-store-stock-alert/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "amazonAsins": ["B0FGJF172R"],
    "ebayKeywords": ["zojirushi travel mug"],
    "titleMustContain": ["mug"],
    "targetPrice": 30
  }'
```

### Pricing

You pay $0.05 for each source actually checked, so a two-store watch costs less than a three-store one.

**The source Actors bill their own usage on top of this**, because this Actor runs them for you: Amazon Price Tracker at $0.01 per product, eBay Price Tracker at $0.02 per search, Shopify Price Tracker at $0.02 per store. A daily watch on 2 ASINs plus 1 eBay search costs about $0.14 a day all in.

| Watching one product across 3 stores daily | Monthly cost |
| --- | --- |
| Checking by hand | roughly 10 hours |
| Most price comparison tools | $30 to $150 per month |
| This Actor, all sources included | around $5 per month |

### Common questions

**Why did a source come back empty?** Each source reports its own status in the run summary, with the error if it failed. eBay occasionally challenges even from residential exits; the source Actor retries on fresh sessions, and if it still fails the other stores are reported anyway.

**Do I have to use all three stores?** No. Leave any of the three inputs empty and that source is skipped entirely, and not charged.

**How does it know two listings are the same product?** It does not try to match them automatically, because fuzzy product matching across marketplaces gets it wrong quietly. You scope the run with `titleMustContain`, which is explicit and predictable.

**Where is the price history kept?** In the source Actors. Each one tracks its own baseline, so `changeType` arrives already computed and history builds from your first run.

### Related products

- **Amazon Price Tracker** to watch Amazon on its own
- **Amazon Stock & Buy Box Alert** to watch who is winning the buy box
- **eBay Price Tracker** to watch eBay on its own
- **Shopify Price Tracker** to watch any Shopify storefront
- **Amazon Deals & Coupon Monitor** to find discounts you are not yet tracking

# Actor input Schema

## `productLabel` (type: `string`):

An optional name for what you are tracking, copied onto every row so several scheduled runs stay readable in one dataset.

## `amazonAsins` (type: `array`):

ASINs or Amazon product URLs to check. Leave empty to skip Amazon entirely.

## `amazonMarketplace` (type: `string`):

Which Amazon site to price against.

## `ebayKeywords` (type: `array`):

What to search for on eBay. Leave empty to skip eBay entirely.

## `ebaySite` (type: `string`):

Which eBay site to search. Keep this in the same country as the Amazon marketplace so prices are comparable.

## `shopifyStores` (type: `array`):

Shopify storefront domains to check, for example gymshark.com. Leave empty to skip Shopify entirely.

## `titleMustContain` (type: `array`):

Keep only offers whose title contains one of these words. Strongly recommended whenever a Shopify store is included, because a storefront returns its whole catalogue and an unscoped comparison will name an unrelated product as the cheapest.

## `maxShopifyProductsPerStore` (type: `integer`):

Upper limit on how many products to read from each Shopify store.

## `targetPrice` (type: `integer`):

Alert when any in-stock offer reaches this price or lower. 0 turns the target off.

## `onlyAlerts` (type: `boolean`):

Return only price drops, stock flips, new listings and buy box changes. Turn this on for scheduled monitoring.

## `onlyInStock` (type: `boolean`):

Drop anything that cannot actually be bought right now.

## `maxPrice` (type: `integer`):

Keep only offers at or below this price. 0 means no maximum.

## `sourceTimeoutSecs` (type: `integer`):

How long each source Actor may run before it is given up on. One slow source will not stop the others being reported.

## Actor input object example

```json
{
  "amazonAsins": [
    "B0FGJF172R"
  ],
  "amazonMarketplace": "US",
  "ebayKeywords": [
    "zojirushi travel mug"
  ],
  "ebaySite": "US",
  "titleMustContain": [
    "travel mug"
  ],
  "maxShopifyProductsPerStore": 1000,
  "targetPrice": 0,
  "onlyAlerts": false,
  "onlyInStock": false,
  "maxPrice": 0,
  "sourceTimeoutSecs": 600
}
```

# Actor output Schema

## `offers` (type: `string`):

One row per offer from Amazon, eBay and Shopify, normalised to the same shape, with the cheapest one flagged.

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

The cheapest source overall, the cheapest within each store, whether your target price was met, and how each source Actor fared.

# 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 = {
    "amazonAsins": [
        "B0FGJF172R"
    ],
    "ebayKeywords": [
        "zojirushi travel mug"
    ],
    "titleMustContain": [
        "travel mug"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("arched_friend/multi-store-stock-alert").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 = {
    "amazonAsins": ["B0FGJF172R"],
    "ebayKeywords": ["zojirushi travel mug"],
    "titleMustContain": ["travel mug"],
}

# Run the Actor and wait for it to finish
run = client.actor("arched_friend/multi-store-stock-alert").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 '{
  "amazonAsins": [
    "B0FGJF172R"
  ],
  "ebayKeywords": [
    "zojirushi travel mug"
  ],
  "titleMustContain": [
    "travel mug"
  ]
}' |
apify call arched_friend/multi-store-stock-alert --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,arched_friend/multi-store-stock-alert"
        }
    }
}
```

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/YKUONAnDfoyVpG2IK/builds/BMbVacOEJ8cWAcROB/openapi.json
