# Lowe's Scraper · Products, Prices, Store Stock & Specs (`memo23/lowes-scraper`) Actor

Scrape Lowe's by category, search or product URL, keyword or item number. Get price, was price, sale end date, rating, reviews, stock by fulfilment method, and one store's price, shelf count and pickup. Add full specs, description, UPC, dimensions and manuals per product. JSON, CSV, Excel.

- **URL**: https://apify.com/memo23/lowes-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** E-commerce
- **Stats:** 1 total users, 1 monthly users, 80.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 results

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

## Lowe's Scraper · Products, Prices, Store Stock & Specs

**Turn Lowe's category pages, searches and product pages into clean product rows.** Each row carries the current price, the was price and the date a sale ends, the rating and review count, stock for every way Lowe's fulfils an order and, for a store you pick, that store's price, shelf quantity and pickup availability. Switch on product-page details for the full specification table, description, UPC, dimensions and manuals. Export as JSON, CSV or Excel.

### Why Use This Scraper?

- ✅ **Store-level prices and stock.** Pick a Lowe's store and category rows come back with that store's price, units on the shelf and pickup status, the numbers a shopper at that store sees.
- ✅ **Whole categories, past Lowe's own limit.** A Lowe's listing stops near 600 products. When you want more, the actor walks the category's subcategories, or its brands, and removes duplicates.
- ✅ **Sale tracking built in.** Price, was price, savings in dollars and percent, and the day the promotion ends.
- ✅ **Stock you can act on.** Availability and quantity for parcel, pickup, delivery and expedited delivery, the online quantity, and the earliest parcel delivery date.
- ✅ **The full product record when you need it.** Product-page details add the long description, feature bullets, the complete specification table (41 rows for a cordless drill), UPC, dimensions and weight, and manual PDFs.
- ✅ **Fails loudly.** A run that could not fetch anything ends `FAILED` with the reason, never as an empty success.

### Overview

The Lowe's Scraper is built for price trackers, resellers, brands and product researchers who need structured product data from lowes.com.

Every input becomes product rows. A category URL, a best-seller page, a keyword, a search URL, a product URL and an item number all produce the same row shape, and the `source` field says which kind of input produced each row.

Category and best-seller listings are read from Lowe's own listing data, 24 products a page, and they use a selected store's prices and stock. Keyword searches and product pages carry national prices; a selected store does not apply to them.

Lowe's only answers US residential connections. The actor brings its own, so there is no proxy to set up.

### Supported Inputs

#### URL types

| URL type | Pattern | Example |
|---|---|---|
| Category | `/pl/{path}/{id}` | `https://www.lowes.com/pl/power-tools/drills-drivers/4294607728` |
| Category narrowed to a brand | `/pl/{path}/{brand}/{id}-{brandId}` | `https://www.lowes.com/pl/power-tools/drills-drivers/dewalt/4294607728-4294926871` |
| Best sellers | `/best-sellers/{path}/{id}` | `https://www.lowes.com/best-sellers/heating-cooling/fireplaces-stoves/chimney-pipe-accessories/chimney-pipe/4294506739` |
| Search | `/search?searchTerm={keyword}` | `https://www.lowes.com/search?searchTerm=cordless+drill` |
| Product | `/pd/{slug}/{productId}` | `https://www.lowes.com/pd/Kobalt-24-volt-Max-1-2-in-Metal-Ratcheting-Brushless-Cordless-Drill-1-Battery-Included-and-Charger-Included/5013207487` |

#### Copy-pasteable startUrls

```json
{
  "startUrls": [
    { "url": "https://www.lowes.com/pl/power-tools/drills-drivers/4294607728" },
    { "url": "https://www.lowes.com/search?searchTerm=cordless+drill" },
    { "url": "https://www.lowes.com/pd/Kobalt-24-volt-Max-1-2-in-Metal-Ratcheting-Brushless-Cordless-Drill-1-Battery-Included-and-Charger-Included/5013207487" }
  ],
  "maxItems": 100
}
```

#### Keywords and item numbers

No URL needed. Each keyword runs as its own Lowe's search, and each item number or product ID becomes one product row:

```json
{
  "searchQueries": ["cordless drill", "impact driver"],
  "itemIds": ["5013207487", "4913878"],
  "maxItems": 50
}
```

#### Unsupported inputs

- ❌ Department landing pages (`lowes.com/c/…`): they have no product list. Open a category under them and paste its `/pl/` URL.
- ❌ Sites other than lowes.com, such as lowes.ca.
- ❌ Review text and questions and answers: rows carry the rating and review count only.
- ❌ Anything behind a MyLowe's or Pro account, such as Pro pricing, lists or order history.
- ❌ Several stores in one run: run once per store.

### Use Cases

| Audience | Use case |
|---|---|
| **Price trackers and deal sites** | Schedule a category or an item list and compare `price`, `wasPrice`, `onSale` and `saleEndsOn` between runs |
| **Local shoppers and resellers** | Check one store's shelf quantity and pickup availability before a trip or a resale buy |
| **Brands and manufacturers** | Watch your products' Lowe's price, promotions, rating, review count and rank in a category |
| **Market researchers** | Export a category's assortment with brands, key specs and Lowe's merchandising tree |
| **Catalog and data teams** | Pull UPCs, model numbers, dimensions, specifications and manuals for product matching |

### How It Works

1. **Input.** Lowe's URLs, keywords or item numbers, and optionally one store.
2. **Route.** Category and best-seller URLs are paged through Lowe's listing data with the selected store's prices and stock. Keywords, search URLs and product pages are fetched from Lowe's web pages at national prices.
3. **Reach the whole category.** Past about 600 products, a category is split into its subcategories or brands, and duplicates are dropped.
4. **Filter and cap.** Sale, stock and price filters remove rows before they are written, and `maxItems` ends the run.
5. **Details and output.** With `includeDetails`, each kept product's page adds specifications, description, UPC, dimensions and manuals. One row per product lands in the dataset, ready for JSON, CSV or Excel.

### Input Configuration

#### Input fields

| Field | Type | Default | Notes |
|---|---|---|---|
| `startUrls` | `array<{ url }>` | – | Category, brand-filtered category, best-seller, search and product URLs, in any mix. The console prefills a drills category. |
| `searchQueries` | `array<string>` | `[]` | Keywords, each run as a Lowe's search, up to about 740 results. National prices. |
| `itemIds` | `array<string>` | `[]` | Lowe's item numbers (`4913878`) or product IDs (`5013207487`). National prices. |
| `maxItems` | `integer` | `100` | Cap on product rows across all sources, and so on billing. Filtered-out rows do not count. Free-plan users get at most 50 per run. |
| `includeDetails` | `boolean` | `false` | Open each product's page for description, bullets, full specs, UPC, dimensions, manuals, ENERGY STAR and exclusive flags, and the listing date. Billed as one `additional-data` event per row that gets them. |
| `storeId` | `string` | – | Store number, e.g. `0595`. Category and best-seller rows then carry that store's price, `storeQuantity` and pickup status. |
| `zipCode` | `string` | – | US ZIP code, used to find the nearest store when `storeId` is empty. The log names the store it picked; if none is found, prices stay national and the log says so. |
| `sort` | `string` | `featured` | Category order: `featured`, `bestSellers`, `highestRated`, `newest`, `priceLowToHigh`. Keyword searches keep Lowe's relevance order. |
| `splitLargeCategories` | `boolean` | `true` | Walk subcategories, or brands, when a category holds more than about 600 products and `maxItems` asks for more. |
| `onSaleOnly` | `boolean` | `false` | Keep only products with a was price. |
| `inStockOnly` | `boolean` | `false` | With a store: keep products on its shelf. Without one: keep products available through at least one fulfilment method. |
| `minPrice` / `maxPrice` | `number` | – | Price band in USD. For a price range, the low end is compared. |
| `maxConcurrency` | `integer` | `6` | Listings and product pages fetched in parallel, 1 to 16. |
| `cacheMaxAgeHours` | `integer` | `1` | Keyword and product pages your own earlier runs fetched within this many hours are reused, so repeat runs finish in seconds. Kept per account, never shared with another user. Category listings are always fetched live. A reused page carries the price and stock it had when it was fetched, so a longer window trades freshness for speed; `0` always fetches fresh. |
| `proxy` | `object` | built-in | Optional own proxy URLs, US residential only. Apify Proxy settings in this field are not used. |

#### Common scenarios

**1. Sale check for one category at your store**

```json
{
  "startUrls": [{ "url": "https://www.lowes.com/pl/power-tools/drills-drivers/4294607728" }],
  "storeId": "0595",
  "onSaleOnly": true,
  "maxItems": 200
}
```

**2. Full records for a list of products**

```json
{
  "itemIds": ["5013207487", "5015141809"],
  "includeDetails": true,
  "maxItems": 10
}
```

**3. A whole large category**

```json
{
  "startUrls": [{ "url": "https://www.lowes.com/pl/power-tools/drills-drivers/4294607728" }],
  "splitLargeCategories": true,
  "maxItems": 2000
}
```

**4. Keyword research within a price band**

```json
{
  "searchQueries": ["pressure washer"],
  "maxPrice": 300,
  "maxItems": 100
}
```

### Output Overview

Each dataset item is one product. Prices are USD numbers. Every row has the same fields: when Lowe's did not provide a value it is `null` or an empty list, so CSV columns stay stable from run to run.

- **Identity:** product ID, item number, model number, brand, title, URL, category path and Lowe's merchandising tree.
- **Price:** price, was price, savings, savings percent, sale flag and sale end date. Products sold in several variants carry `priceMin` and `priceMax` instead of `price`.
- **Stock:** availability per fulfilment method with quantities, online quantity, earliest delivery date, pickup and free-shipping flags.
- **Store:** store number, store name and shelf quantity, when a store is selected and the row came from a category or best-seller listing.
- **Listing context:** which input produced the row, its rank among organic results, the page, sponsored and marketplace flags, badges, key specs, images and videos.
- **Details:** description, highlights, specifications, UPC, dimensions, manuals and flags, when `includeDetails` is on.

**On the free Apify plan,** the first 3 products of each run come back in full, so you can check the data. After that, rows keep the product itself - item ID, item number, model number, brand, title, URL, images, videos, key specs, merchandising badges, rating, review count, category path, the sale flag and the selected store - while the price fields, the stock and fulfilment block (availability, inStock, onlineQuantity, storeQuantity, pickup, free shipping, delivery date) and the `includeDetails` payload (highlights, specifications, UPC, dimensions, manuals; the description is shortened) are left empty, and the row carries a `freePlanNote` saying so. Promotion badges that print a price ("Save $30", "Was $299", "New Lower Price") are dropped from `badges` on those rows too, so the hidden price cannot come back through a label; merchandising badges such as "Top Gift" stay. Any paid Apify plan returns every field for every product.

### Output Samples

#### Category row with a store selected (trimmed)

From `https://www.lowes.com/pl/power-tools/drills-drivers/4294607728` with `"storeId": "0595"`:

```json
{
  "itemId": "5013207487",
  "itemNumber": "4913878",
  "modelNumber": "KDD 2024A-03",
  "brand": "Kobalt",
  "title": "Kobalt 24-volt 1/2-in Keyless Brushless Cordless Drill 1 -Batteries Included, and Charger Included",
  "url": "https://www.lowes.com/pd/Kobalt-24-volt-Max-1-2-in-Metal-Ratcheting-Brushless-Cordless-Drill-1-Battery-Included-and-Charger-Included/5013207487",
  "price": 99,
  "wasPrice": 159,
  "savings": 60,
  "savingsPercent": 37,
  "onSale": true,
  "saleEndsOn": "2026-10-21",
  "currency": "USD",
  "rating": 4.6,
  "reviewCount": 596,
  "imageUrl": "https://mobileimages.lowes.com/productimages/2ebf015b-659b-4c82-b909-38aa892c89c4/97265246.jpeg",
  "keySpecs": { "Cordless": "Yes", "Brushless": "Yes", "Battery Included": "Yes" },
  "badges": ["Top Gift"],
  "availability": [
    { "method": "Parcel", "available": true, "quantity": 503 },
    { "method": "Pickup", "available": true, "quantity": 517 },
    { "method": "Delivery", "available": true, "quantity": 532 },
    { "method": "ExpeditedDelivery", "available": true, "quantity": 29 }
  ],
  "inStock": true,
  "onlineQuantity": 503,
  "deliveryDate": "2026-09-30",
  "pickupAvailable": true,
  "freeShipping": true,
  "storeNumber": "0595",
  "storeName": "Mooresville Lowe's",
  "storeQuantity": 14,
  "categoryPath": ["Tools", "Power Tools", "Drills & Drivers"],
  "source": "category",
  "sourceQuery": "Drills & Drivers",
  "position": 1,
  "page": 1,
  "detailsScraped": false,
  "scrapedAt": "2026-09-28T20:20:32.333Z"
}
```

#### The same product with `includeDetails: true` (detail fields only, trimmed)

```json
{
  "itemId": "5013207487",
  "detailsScraped": true,
  "description": "This new generation Kobalt drill driver uses the most innovative electronics and motor technology to deliver up to 850 in-lb of torque…",
  "highlights": [
    "Innovative brushless motor boosts up to 850 in-lb of torque and 2,000 Max RPM",
    "Compact design with comfortable soft grip and superior balance"
  ],
  "specifications": {
    "Battery Type": "Lithium ion (Li-ion)",
    "Battery Voltage": "24-volt",
    "Chuck Type": "Keyless",
    "Case Type": "Soft"
  },
  "upc": "195532000342",
  "dimensions": { "heightIn": 9.45, "widthIn": 6.3, "depthIn": 12.8, "weightLb": 8.11 },
  "manuals": [
    { "title": "Use and Care Manual", "type": "USE_AND_CARE_GUIDE", "url": "https://pdf.lowes.com/productdocuments/bdb07167-0a9c-457e-87b1-f25257337efb/60077854.pdf" }
  ],
  "energyStar": false,
  "lowesExclusive": false,
  "listedAt": "2021-10-21T12:01:46.266Z"
}
```

This row had 41 specifications, 9 highlights, 18 images, 2 videos and 2 manuals before trimming.

### Key Output Fields

#### Identity

- `itemId`, `itemNumber`, `modelNumber`, `brand`, `title`, `url`
- `categoryPath[]`, `merchandising{}` (Lowe's division, product group and assortment)

#### Price

- `price`: what the buyer pays now; `priceMin` / `priceMax` for products sold as a range
- `wasPrice`, `savings`, `savingsPercent`, `onSale`, `saleEndsOn`, `currency`
- `priceNote`: set when the price fields are empty and why. Lowe's shows no price for some products, appliances above all, until it knows the shopper's location. Keyword and product rows are fetched without a store, so the actor retries those pages a couple of times and then sets this note. A category URL with `storeId` gets the store's price.

#### Stock and fulfilment

- `inStock`: available through at least one fulfilment method
- `availability[]`: `method`, `available`, `quantity` for Parcel, Pickup, Delivery, ExpeditedDelivery
- `onlineQuantity`, `deliveryDate`, `pickupAvailable`, `freeShipping`, `isBuyable`

#### Store (with `storeId` or `zipCode`)

- `storeNumber`, `storeName`, `storeQuantity` (units on the shelf at that store)

#### Listing context

- `source` (`category` / `search` / `product`), `sourceQuery`, `sourceUrl`, `position`, `page`
- `rating`, `reviewCount`, `badges[]`, `keySpecs{}`, `isSponsored`, `isMarketplace`, `imageUrl`, `images[]`, `videos[]`

#### Details (with `includeDetails`)

- `detailsScraped`, `description`, `highlights[]`, `specifications{}`, `upc`, `dimensions{}`, `manuals[]`, `energyStar`, `lowesExclusive`, `listedAt`

### FAQ

#### Which Lowe's URLs are supported?

Category pages (`/pl/…`), brand-filtered category pages, best-seller pages (`/best-sellers/…`), search pages (`/search?searchTerm=…`) and product pages (`/pd/…`). Department landing pages (`/c/…`) have no product list; use a category under them. Anything the actor cannot use is listed in the run log with the reason, and the rest of the run goes on.

#### Why do keyword results show national prices when I set a store?

A selected store applies to category and best-seller listings, the part of Lowe's the actor reads with the store set. Keyword searches and product pages come back at national prices. When Lowe's answers a keyword with a category page, the actor pages that category instead, and the store applies there. Prices and sale flags can differ between the national listing and a store.

#### How many products can one category return?

One Lowe's listing stops near 600 products. With `splitLargeCategories` on (the default) and `maxItems` above 600, the actor walks the category's subcategories, or its brands when it has none, to reach the rest. A keyword search returns up to about 740 results.

#### What is the difference between `storeQuantity` and `availability`?

`storeQuantity` is the number of units on the shelf at the store you selected. The quantities in `availability` are Lowe's totals for each fulfilment method across its network.

#### Why is `price` null on some rows?

The product is sold in several variants and Lowe's shows a price range. `priceMin` and `priceMax` carry the range.

#### Does it scrape reviews?

No. Each row has the rating and the review count, not the review text.

#### When is `includeDetails` worth it?

When you need the specification table, UPC, dimensions, description or manuals. It opens one extra page per product, so a run takes longer, and each row that gets the details is billed one `additional-data` event. For price and stock monitoring, the listing rows are enough.

#### Do I need proxies?

No. Lowe's refuses non-US and datacenter connections, and the actor uses its own US residential connection. If you enter your own proxy URLs, they must be US residential.

#### Can it read my account, Pro pricing or order history?

No. The actor only reads public product pages and listings; nothing behind a MyLowe's or Pro login.

#### Why did my run end `FAILED`?

A run that could not fetch any of its sources ends `FAILED` with the reason in the status message, for example when your own proxies are not US residential. A run whose sources worked but whose filters removed every product ends `SUCCEEDED` with no rows.

### Support

- For issues or feature requests, please use the [Issues](https://apify.com/memo23/lowes-scraper/issues) tab of this actor.
- If you need customization or have questions, contact the author:
  - Author's website: <https://muhamed-didovic.github.io/>
  - Email: <muhamed.didovic@gmail.com>

### Additional Services

- Request customization or a whole dataset: <muhamed.didovic@gmail.com>
- If you need anything else scraped, or this actor customized, email: <muhamed.didovic@gmail.com>
- For API services of this scraper (no Apify fee, just usage fee for the API), contact: <muhamed.didovic@gmail.com>

### Explore More Scrapers

- [Wayfair Scraper](https://apify.com/memo23/wayfair-scraper): home goods products, prices, stock and ratings
- [Free Amazon Product Scraper](https://apify.com/memo23/free-amazon-product-scraper): Amazon prices and search results
- [Etsy Scraper](https://apify.com/memo23/etsy-scraper): cart demand, ad slots, prices and shop reviews

Full list at [apify.com/memo23](https://apify.com/memo23).

### 🤖 For AI Agents & LLM Apps

Compact reference for agents calling this actor through the [Apify MCP server](https://mcp.apify.com) or the Apify API (actor: `memo23/lowes-scraper`).

**Purpose:** Lowe's product rows from category, best-seller, search or product URLs, keywords or item numbers, with price, sale, stock by fulfilment method and one selected store's price and shelf quantity.

**Minimal input:**

```json
{ "startUrls": [{ "url": "https://www.lowes.com/pl/power-tools/drills-drivers/4294607728" }], "maxItems": 10 }
```

**Output:** one row per product: itemId, itemNumber, modelNumber, brand, title, url, price, priceMin, priceMax, wasPrice, savings, savingsPercent, onSale, saleEndsOn, priceNote, currency, rating, reviewCount, imageUrl, images, videos, keySpecs, badges, availability {method, available, quantity}, inStock, onlineQuantity, deliveryDate, pickupAvailable, freeShipping, storeNumber, storeName, storeQuantity, merchandising, categoryPath, source, sourceQuery, sourceUrl, position, page, detailsScraped, scrapedAt; with includeDetails also description, highlights, specifications, upc, dimensions {heightIn, widthIn, depthIn, weightLb}, manuals, energyStar, lowesExclusive, listedAt.

**Behaviors an agent should know:**

- Always set `maxItems`: every product row is billed, and a large category can yield thousands of rows. Free-plan users are capped at 50 per run.
- `includeDetails` adds one billed `additional-data` event per row that got details. Rows removed by `onSaleOnly`, `inStockOnly`, `minPrice` or `maxPrice` are not billed.
- A store (`storeId`, or `zipCode`) applies to category and best-seller rows only; keyword and product rows are national. Tell the user when that matters.
- Department pages (`/c/…`) and non-lowes.com hosts are skipped and logged. Review text and account-only prices are not available.
- On the free Apify plan, rows after the first 3 come back with the price, stock and detail fields empty and a `freePlanNote` set; identity, images, rating and store stay. Paid plans get full rows.
- A run that fetched nothing ends `FAILED` with the cause in its status message; an empty result after successful fetches ends `SUCCEEDED`.

### ⚠️ Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Lowe's Companies, Inc. or any of its subsidiaries. All trademarks mentioned are the property of their respective owners.

The scraper accesses only publicly available product pages and listings on lowes.com. It uses no accounts, no Pro or member pricing and nothing behind the lowes.com login. Users are responsible for making sure their use complies with Lowe's Terms of Use, applicable data-protection law (GDPR, CCPA, etc.), and any contractual obligations of their own organization.

### SEO Keywords

lowe's scraper, lowes scraper, scrape lowes, lowes.com scraper, lowe's product scraper, lowes api, Apify lowes, lowe's price tracker, lowe's store inventory checker, lowe's stock checker, lowe's sale tracker, lowe's best sellers scraper, lowe's category scraper, lowe's upc lookup, lowe's product specifications, home improvement price monitoring, hardware store price data, power tools price tracker, building supplies product data, retail price monitoring, home improvement product data

# Actor input Schema

## `startUrls` (type: `array`):

Lowe's pages to scrape, in any mix: category listings (<code>lowes.com/pl/…/4294607728</code>, a brand in the path works too), best-seller pages (<code>lowes.com/best-sellers/…/{id}</code>), search pages (<code>lowes.com/search?searchTerm=cordless+drill</code>) and product pages (<code>lowes.com/pd/…/5013207487</code>). Every source yields product rows. Department landing pages (<code>lowes.com/c/…</code>) have no product list: open a category under them and paste its <code>/pl/</code> URL. Example: <code>https://www.lowes.com/pl/power-tools/drills-drivers/4294607728</code>.

## `searchQueries` (type: `array`):

Each keyword runs as its own Lowe's search, up to about 740 results. Rows carry national prices. When Lowe's answers a keyword with a category page, that category is paged instead, and a selected store applies there. An item or model number goes straight to its product. Example: <code>cordless drill</code>.

## `itemIds` (type: `array`):

Lowe's item numbers (the "Item #" on the product page and shelf tag, e.g. <code>4913878</code>) or product IDs (the number at the end of a product URL, e.g. <code>5013207487</code>), one per line. Each becomes one product row at national prices.

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

Hard cap on product rows across all sources. Every row is billed, so this is the spending limit. Rows removed by the filters below do not count toward it. Free-plan users get at most 50 per run, and after the first 3 products their rows come back with the price, stock and detail fields empty (a freePlanNote marks them); any paid plan returns every field. Default: 100.

## `includeDetails` (type: `boolean`):

Open each product's own page for the long description, feature bullets, the full specification table, UPC, dimensions and weight, manuals, the ENERGY STAR and Lowe's-exclusive flags, and the date Lowe's first listed it. One extra page per product, so runs take longer, and each row that gets these fields is billed one extra <code>additional-data</code> event. Off by default: listing rows already carry price, sale, rating, stock and key specs.

## `storeId` (type: `string`):

Store number, e.g. <code>0595</code> (Mooresville, NC); leading zeros are optional. Category and best-seller listings then carry that store's price, shelf quantity (<code>storeQuantity</code>) and pickup availability. Keyword searches and product pages stay at national prices. Leave empty for national prices.

## `zipCode` (type: `string`):

Five-digit US ZIP code, e.g. <code>28117</code>, used to find the nearest store when <b>Lowe's store number</b> is empty. The run log names the store it picked. If no store is found, prices stay national and the log says so; a store number skips the lookup.

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

Order of category listings, which decides which products come first when Max products ends the run early. Best-seller URLs keep their best-seller order unless you pick another sort here. Keyword searches keep Lowe's own relevance order. Default: Featured.

## `splitLargeCategories` (type: `boolean`):

One Lowe's listing pages through about 600 products. When a category holds more and Max products asks for more than 600, the run walks its subcategories (or, for a category without any, its brands) to reach the rest, with duplicates removed. Turn off to stop at the first 600 of each category. Default: on.

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

Keep only products with a was price, meaning Lowe's currently shows them marked down. Default: off.

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

With a store selected, keep only products on the shelf there (storeQuantity above 0). Without a store, keep products available through at least one fulfilment method (parcel, pickup or delivery). Default: off.

## `minPrice` (type: `number`):

Drop products priced below this many US dollars, e.g. <code>25</code>. For a product sold as a price range, the low end is compared. Empty means no lower bound.

## `maxPrice` (type: `number`):

Drop products priced above this many US dollars, e.g. <code>200</code>. For a product sold as a price range, the low end is compared. Empty means no upper bound.

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

Category listings and product pages fetched in parallel, from 1 to 16. Raise it to speed up large runs with product-page details. Default: 6.

## `cacheMaxAgeHours` (type: `integer`):

When one of your earlier runs already fetched a Lowe's search or product page, reuse it if it is younger than this many hours instead of fetching it again. Repeat runs then finish in seconds instead of minutes, and the pages are kept per account: only your own runs' pages are reused, never another user's. Category listings are always fetched live. <b>What a longer window costs you:</b> a reused page carries the price, sale, fulfilment and stock that were on it when it was fetched, so at 24 hours you can be reading yesterday's price as today's. The default of 1 hour is chosen for that reason — it is long enough to stop one bulk job fetching the same product page twice, short enough that the figure is still current. Set 0 to always fetch fresh. Default: 1.

## `proxy` (type: `object`):

Leave empty and the actor uses its own US residential connection, which Lowe's requires. To use your own proxies instead, enter custom proxy URLs: they must be US residential exits, because Lowe's refuses datacenter and non-US IPs. They carry the category listings; keyword searches and product pages always go through the actor's own page service. Apify Proxy settings in this field are not used.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.lowes.com/pl/power-tools/drills-drivers/4294607728"
    }
  ],
  "searchQueries": [],
  "itemIds": [],
  "maxItems": 100,
  "includeDetails": false,
  "sort": "featured",
  "splitLargeCategories": true,
  "onSaleOnly": false,
  "inStockOnly": false,
  "maxConcurrency": 6,
  "cacheMaxAgeHours": 1
}
```

# Actor output Schema

## `products` (type: `string`):

One row per product: itemId, itemNumber, modelNumber, brand, title, url, price, priceMin, priceMax, wasPrice, savings, savingsPercent, onSale, saleEndsOn, priceNote, rating, reviewCount, images, videos, keySpecs, badges, availability, inStock, onlineQuantity, deliveryDate, pickupAvailable, freeShipping, storeNumber, storeName, storeQuantity, merchandising, categoryPath, source, sourceQuery, position, page, scrapedAt; with product-page details also description, highlights, specifications, upc, dimensions, manuals, energyStar, lowesExclusive, listedAt.

# 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 = {
    "startUrls": [
        {
            "url": "https://www.lowes.com/pl/power-tools/drills-drivers/4294607728"
        }
    ],
    "searchQueries": [],
    "itemIds": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/lowes-scraper").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 = {
    "startUrls": [{ "url": "https://www.lowes.com/pl/power-tools/drills-drivers/4294607728" }],
    "searchQueries": [],
    "itemIds": [],
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/lowes-scraper").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 '{
  "startUrls": [
    {
      "url": "https://www.lowes.com/pl/power-tools/drills-drivers/4294607728"
    }
  ],
  "searchQueries": [],
  "itemIds": []
}' |
apify call memo23/lowes-scraper --silent --output-dataset

```

## MCP server setup

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

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/UdXFyo069qoIj64Xf/builds/KIdf9XfLJG9t2qYcn/openapi.json
