# Mark's (marks.com) Product Search Scraper – CAD Prices & Sales (`loudtzu/marks-ca-product-search`) Actor

Export marks.com (Mark's) search results: name, brand, CAD price, was price, sale flag and sale end date, review count, badges, every colourway with its own price, and feature bullets. $0.00056 per product + $0.0005 per run. API runs without keywords search "work boots".

- **URL**: https://apify.com/loudtzu/marks-ca-product-search.md
- **Developed by:** [LOUDTZU TZULOUD](https://apify.com/loudtzu) (community)
- **Categories:** E-commerce, Business
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.56 / 1,000 products

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

## Mark's (marks.com) Product Search Scraper – CAD Prices & Sales

Exports marks.com (Mark's / Mark's Work Wearhouse) search results with CAD prices, sale flags and sale end dates. For products sold in several colours, it also gives **the price of every colourway**. It reads the public search that marks.com's own pages use. No login. It runs on the Apify datacenter proxy.

### What it returns

For each product:

- **Product:** name, product code, brand, link and image.
- **Price:** the lowest current price across its colours, in CAD. Also the highest colour price when the colours differ.
- **Sale:** the regular ("was") price, an on-sale flag and the sale end date marks.com shows.
- **Reviews and badges:** number of ratings (null when there are none), and badges such as Top Rated or Sale.
- **Colours:** every colourway with its own price, was price, sale flag, sale end date, number of sizes and link.
- **Counts:** number of SKUs, which is every colour and size combination.
- **Features:** the product's feature bullets.

### How to use

1. Add one or more search terms, for example `work boots` or `jeans`.
2. Pick a sort order and, if you want, only products on sale.
3. Set **Max products**. It is split evenly between the search terms.

### Input

| Field | Description |
|---|---|
| `keywords` | Search terms |
| `sort` | `relevance`, `price_low`, `price_high`, `rating` |
| `onSaleOnly` | Skip products where no colour is on sale |
| `maxItems` | Total products (default 100, up to 50,000) |
| `fetchAll` | Save every result, up to 50,000 |

Other input keys (for example `language`) are ignored, and the run log shows a warning for each one.

If an API run leaves out `keywords`, the Actor searches the default term `work boots`. An empty list or a blank line is not treated as missing: the run fails before any charge.

### Output

`productId`, `name`, `brand`, `url`, `price`, `priceMax`, `wasPrice`, `isOnSale`, `saleEndDate`, `currency`, `reviewsCount`, `badges`, `colours`, `colourCount`, `skuCount`, `features`, `image`, `searchQuery`, `page`, `position`.

Example (shortened):

```json
{"productId": "12609106F", "name": "Denver Hayes Men's FLEXTECH 360 Stone Washed Relaxed Tapered Leg Stretch Jeans", "brand": "Denver Hayes", "price": 34.99, "priceMax": null, "wasPrice": 69.99, "isOnSale": true, "saleEndDate": "November 4, 2026", "reviewsCount": 637, "badges": ["TOPRATED", "SALE", "Flash_Sale"], "colourCount": 1, "colours": [{"colour": "Denim", "price": 34.99, "wasPrice": 69.99, "onSale": true, "saleEndDate": "November 4, 2026", "sizeCount": 46}], "url": "https://www.marks.com/en/pdp/denver-hayes-men-s-flextech-360-stone-washed-relaxed-tapered-leg-stretch-jeans-12609106f.html"}
```

### Fill rates in a sample

This sample was 100 results for `jeans`, taken on Oct 29, 2026.

- Filled for all 100: `name`, `brand`, `price`, `colours`, `badges`, `features`, `image` and `url`.
- `reviewsCount`: 99 of 100 (null for the product with no ratings).
- On sale: 84 of 100. `wasPrice` and `saleEndDate` were filled for all 84.
- `priceMax`: 1 of 100. It is only set when colours have different prices.

### Limits

- **English only.** marks.com's search service does not answer French requests.
- **Search-result data only.** No average star rating (the search does not provide it, only the count), no review text, no per-size stock and no store stock.
- Prices are the online prices marks.com shows by default.
- **Range-priced colourways.** Some colourways have no single price: marks.com sends `{value: null, minPrice: 189.99, maxPrice: null}`, usually because sizes are priced differently. Then the colourway's `price` is `minPrice` (the "from" price) and its `priceMax` is `maxPrice` when marks.com sends one. The regular (`was`) price is read the same way.
- **Prices that can still be empty:** `price` (product or colourway) is null only when marks.com sends no `value`, `minPrice` or `maxPrice` at all. `priceMax` is null when every colour and size has the same price, or when marks.com sends no upper price for a range. `wasPrice` is null when the item is not discounted, and for clearance items where marks.com sends no regular price.
- **Clearance and sale.** `isOnSale` is true when marks.com flags the item on sale, or when it carries a `CLEARANCE`, `SALE` or `Flash_Sale` badge. In-cart promotions ("Take 25% off in-cart") do not count, because the listed price does not change. A product can carry a `CLEARANCE` badge while no colourway in the search shows a clearance price (usually only some sizes are cleared); it is then `isOnSale: true` with `wasPrice` null and full colour prices. Clearance items have no sale end date: `saleEndDate` is null for them.
- `saleEndDate` is the text marks.com shows (for example `November 4, 2026`), not reformatted.
- A blank or whitespace-only search fails the run at once with a clear message, before any request or charge.
- If no products are saved, the run is marked failed, the reason goes in the `ERRORS` record, and nothing is charged.
- No personal data is collected.

### Pricing

Pay per event:

- **$0.00056 per product** saved.
- **$0.0005 per run**, charged only after the first product is saved. Runs that save nothing cost nothing.

### Other Actors that cover Mark's on Apify

Prices were checked on the Apify Store on Oct 29, 2026. Neither Actor has plan tiers, so the same price applies on every Apify plan. Start fees for other Actors are shown at their minimum: one start event. alduinxx prices per size and colour row, not per product, so one product with several colours and sizes is charged as several rows there; the per-product figures below understate its cost. Apify charges start events per GB of run memory, so they can be higher.

| Actor | Checked | Price per product | Start fee per run | Notes |
|---|---|---|---|---|
| alduinxx/canadian-tire-sport-chek-marks-scraper | Oct 29, 2026 | $0.00075 | $0.005 | Also Canadian Tire and Sport Chek; store stock and aisle |
| yugenox/canadian-tire-scraper | Oct 29, 2026 | $0.0015 | $0.002 | Also Canadian Tire, Sport Chek and Party City |
| This Actor | Oct 29, 2026 | $0.00056 | $0.0005, only if something is saved | |

Cost at list prices:

| Products | This Actor | alduinxx | yugenox |
|---|---|---|---|
| 1 | $0.00106 | $0.00575 | $0.0035 |
| 10 | $0.0061 | $0.0125 | $0.017 |
| 100 | $0.0565 | $0.080 | $0.152 |
| 1,000 | $0.5605 | $0.755 | $1.502 |

On these list prices, this Actor costs less for any number of products: both the per-product price and the start fee are lower. If you need store-level stock, or Canadian Tire and Sport Chek in the same run, one of the other Actors is a better fit.

### FAQ

#### How much does a run cost?

This Actor uses pay-per-event pricing. You pay only for these events:

- **Run start**: $0.0005 per run – Charged once per run, only after the first product has been saved. Failed runs and runs with 0 products are not charged.
- **Product**: $0.00056 each ($0.56 per 1,000) – One product saved to the dataset.
  Set `maxItems` to cap the cost of a run.

#### How many results can one run return?

Up to `maxItems` (default 100, maximum 50,000).

#### How do I export or automate the results?

Results are saved to the run's dataset. Download them as JSON, CSV, Excel or HTML, read them through the Apify API, or run the Actor on a schedule and send the results to Google Sheets, Slack, Zapier, Make or a webhook.

#### Is this an official Mark's tool?

No. It is an independent tool and is not affiliated with or endorsed by Mark's. It reads only publicly available data.

# Actor input Schema

## `keywords` (type: `array`):

One marks.com search per line. If left out (API runs), the Actor searches "work boots". Empty or whitespace-only lines stop the run before anything is charged.

## `maxItems` (type: `integer`):

Total cap across all keywords (default 100, max 50,000). Split evenly between keywords.

## `fetchAll` (type: `boolean`):

Ignore Max products and save every result the site returns (hard cap 50,000).

## `sort` (type: `string`):

Result order.

## `onSaleOnly` (type: `boolean`):

Skip products where no colourway is on sale.

## Actor input object example

```json
{
  "keywords": [
    "work boots"
  ],
  "maxItems": 100,
  "fetchAll": false,
  "sort": "relevance",
  "onSaleOnly": false
}
```

# Actor output Schema

## `products` (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 = {
    "keywords": [
        "work boots"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("loudtzu/marks-ca-product-search").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 = { "keywords": ["work boots"] }

# Run the Actor and wait for it to finish
run = client.actor("loudtzu/marks-ca-product-search").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 '{
  "keywords": [
    "work boots"
  ]
}' |
apify call loudtzu/marks-ca-product-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,loudtzu/marks-ca-product-search"
        }
    }
}
```

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/zEn3jj4p9JgHe3QEG/builds/efmzy8PZxClePG6LG/openapi.json
