# SustainableSupply Scraper (Cheap) (`data_api/sustainablesupply-scraper-cheap`) Actor

Sustainablesupply product listings scraper that grabs names, prices, SKUs, images, and availability from any collection page, so procurement teams can track catalog data without clicking through pages.

- **URL**: https://apify.com/data\_api/sustainablesupply-scraper-cheap.md
- **Developed by:** [Data API](https://apify.com/data_api) (community)
- **Categories:** Automation, E-commerce, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.99 / 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.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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

## SustainableSupply Product Scraper

![SustainableSupply Product Scraper](cover.jpg)

Copying product details off SustainableSupply.com one page at a time is slow, and the data ends up scattered across browser tabs and half-finished spreadsheets. This scraper reads the store directly and hands you back clean rows: item name, brand, SKU, current price, list price, stock status, weight, images, and more. Point it at a category page or type in a keyword, set how many products you want per source, and download the lot as JSON, CSV, or Excel.

### What you get

Every product comes back as one tidy row. When a value is missing the field is still there, set to `null`, so your columns line up when you load the results into a sheet or database. Each record carries:

- **Identity** — `itemName`, `brandName`, `skuCode`, `gtinCode`, `itemUrl`
- **Pricing** — `currentPrice`, `listPrice`, `savingsAmount`, `currencyCode`
- **Availability and tags** — `stockStatus`, `tagLabels`, `shippingNote`
- **Details** — `itemDescription`, `itemWeight`, `weightUom`, `primaryImage`, `imageUrls`, `collectedAt`

### Quick start

1. Open the actor and click **Try for free**.
2. Paste SustainableSupply category links into **Category page URLs**, or type keywords into **Search keywords** — you can use either or both.
3. Set **Products per URL or keyword** to control how much each source returns.
4. Press **Start**, then download the results as JSON, CSV, or Excel when the run finishes.

![How it works](how-it-works.jpg)

### Use cases

- **Procurement** — line up prices across categories without clicking through page after page
- **Pricing analysis** — watch markdowns by comparing `currentPrice` against `listPrice` over time
- **Product feeds** — build a structured catalog you can drop into a sheet, store, or BI tool
- **Sustainability sourcing** — filter on the `tagLabels` field to surface eco-certified or recycled items
- **Competitor research** — track which brands and SKUs a supplier stocks and at what price

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `categoryUrls` | array of strings | One of `categoryUrls` or `searchTerms` | SustainableSupply collection or category pages to scrape. Each link is handled on its own. |
| `searchTerms` | array of strings | One of `categoryUrls` or `searchTerms` | Plain keywords to look up. Each keyword runs as its own search. |
| `resultsPerSource` | integer | No | Products to pull from each URL or keyword. Default `50`, max `1000`. The cap counts per source. |
| `timeoutSeconds` | integer | No | Seconds to wait on each request before dropping it. Default `45`; raise it on slow connections. |

At least one of `categoryUrls` or `searchTerms` must be filled in.

#### Example input

```json
{
  "categoryUrls": [
    "https://www.sustainablesupply.com/collections/safety-supplies",
    "https://www.sustainablesupply.com/collections/janitorial"
  ],
  "searchTerms": ["trash can", "nitrile gloves"],
  "resultsPerSource": 50,
  "timeoutSeconds": 45
}
````

### Output

Each product becomes one row, and every field is always present — values that don't exist come back as `null`, so your dataset stays rectangular and easy to load.

#### Example output

```json
{
  "itemUrl": "https://www.sustainablesupply.com/products/stainless-steel-touchless-soap-dispenser",
  "itemName": "Stainless Steel Touchless Soap Dispenser, 1000 mL",
  "brandName": "Bobrick",
  "skuCode": "BOB2111",
  "gtinCode": "073555211009",
  "currencyCode": "USD",
  "currentPrice": 129.95,
  "listPrice": 159.95,
  "savingsAmount": 30.00,
  "tagLabels": ["Touchless", "Commercial"],
  "stockStatus": "In Stock",
  "itemDescription": "Wall-mounted touchless dispenser built for high-traffic commercial washrooms, with a refillable 1000 mL reservoir.",
  "shippingNote": "Ships in 3-5 business days.",
  "itemWeight": 4.2,
  "weightUom": "lb",
  "primaryImage": "https://cdn.shopify.com/s/files/1/example-image.jpg",
  "imageUrls": [
    "https://cdn.shopify.com/s/files/1/example-image.jpg"
  ],
  "collectedAt": "2026-06-30T10:32:00.000Z"
}
```

#### Output fields

| Field | Type | Description |
|-------|------|-------------|
| `itemUrl` | string | Direct link to the product page |
| `itemName` | string | Full product title |
| `brandName` | string | Manufacturer or vendor |
| `skuCode` | string | SKU identifier |
| `gtinCode` | string | Barcode (Global Trade Item Number) |
| `currencyCode` | string | Currency the price is quoted in (USD) |
| `currentPrice` | number | Price shown on the listing now |
| `listPrice` | number | Pre-discount price, when the item is marked down |
| `savingsAmount` | number | Amount taken off when the item is on sale |
| `tagLabels` | array | Store tags such as WaterSense or Recycled Content |
| `stockStatus` | string | In Stock or Out of Stock |
| `itemDescription` | string | Plain-text product description |
| `shippingNote` | string | Shipping line pulled from the description, when present |
| `itemWeight` | number | Weight value |
| `weightUom` | string | Weight unit (lb, kg, oz) |
| `primaryImage` | string | Main product image URL |
| `imageUrls` | array | All product image URLs |
| `collectedAt` | string | ISO 8601 timestamp of when the row was captured |

### Tips for best results

- **Prefer category URLs.** Pages under `/collections/` read straight from the store and come back more complete than keyword searches, so use them when you have the choice.
- **Keep the cap in mind.** `resultsPerSource` applies to each URL and each keyword separately — three sources at 50 can return up to 150 products.
- **Start with a small run.** Set `resultsPerSource` to 10 to confirm the output fits your pipeline, then raise it for the full pull.
- **Raise the timeout if requests fail.** Push `timeoutSeconds` to 60 or higher when you see timeout errors on a slow connection.
- **Filter on tags after the run.** The `tagLabels` field is the quickest way to pick out eco-certified or recycled products once you have the data.

### How can I use SustainableSupply product data?

**How can I use the SustainableSupply Product Scraper to build a price list?**
Paste the category pages you care about into `categoryUrls`, set `resultsPerSource`, and run it. Each product returns with `currentPrice`, `listPrice`, `skuCode`, and `brandName`, so you can drop the dataset straight into a spreadsheet and have a working price list in minutes — no copy-paste from the SustainableSupply website.

**How can I track SustainableSupply markdowns and discounts?**
Run the scraper on a schedule and compare `currentPrice` against `listPrice` between runs. The `savingsAmount` field tells you the markdown on any product that's on sale, which makes it easy to spot price drops across a category or watch a few SKUs over time.

**How can I export SustainableSupply products to a spreadsheet or store?**
Every run produces a flat dataset you can download as JSON, CSV, or Excel, or push to Google Sheets, Dropbox, or S3 through Apify integrations. Because each product is one row with consistent keys, it loads cleanly into a product feed, catalog, or BI dashboard without reshaping.

**How can I find eco-friendly products on SustainableSupply at scale?**
Scrape a category or a keyword search, then filter the results on `tagLabels` and `itemDescription`. Tags like WaterSense or Recycled Content surface the sustainable items in bulk, so you can assemble a green-procurement shortlist far faster than browsing the site by hand.

### Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as email addresses or private contact information. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

### Support

Questions, feature requests, or a field you'd like added? Reach out at <data.apify@proton.me> and we'll get back to you.

# Actor input Schema

## `categoryUrls` (type: `array`):

Paste one or more SustainableSupply.com collection or category pages here. Each link should open a product listing — for example a /collections/ page or a search-results page.

## `searchTerms` (type: `array`):

Type plain keywords you want to look up on the store, such as 'paper towel' or 'safety glasses'. Each keyword runs as its own search. Use this on its own or together with category URLs.

## `resultsPerSource` (type: `integer`):

How many products to pull from each individual URL or keyword. The cap is counted per source, so two keywords set to 50 can return up to 100 products in one run.

## `timeoutSeconds` (type: `integer`):

How long to wait on each request before it is dropped. Bump this higher when a slow connection produces timeout errors.

## Actor input object example

```json
{
  "categoryUrls": [
    "https://www.sustainablesupply.com/collections/safety-supplies",
    "https://www.sustainablesupply.com/collections/janitorial"
  ],
  "searchTerms": [
    "trash can",
    "nitrile gloves"
  ],
  "resultsPerSource": 30,
  "timeoutSeconds": 45
}
```

# 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 = {
    "categoryUrls": [
        "https://www.sustainablesupply.com/pages/search-results?q=hand+dryer"
    ],
    "searchTerms": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("data_api/sustainablesupply-scraper-cheap").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 = {
    "categoryUrls": ["https://www.sustainablesupply.com/pages/search-results?q=hand+dryer"],
    "searchTerms": [],
}

# Run the Actor and wait for it to finish
run = client.actor("data_api/sustainablesupply-scraper-cheap").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "categoryUrls": [
    "https://www.sustainablesupply.com/pages/search-results?q=hand+dryer"
  ],
  "searchTerms": []
}' |
apify call data_api/sustainablesupply-scraper-cheap --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=data_api/sustainablesupply-scraper-cheap",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "SustainableSupply Scraper (Cheap)",
        "description": "Sustainablesupply product listings scraper that grabs names, prices, SKUs, images, and availability from any collection page, so procurement teams can track catalog data without clicking through pages.",
        "version": "0.0",
        "x-build-id": "ftuuwoyFVT3YQZr7d"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/data_api~sustainablesupply-scraper-cheap/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-data_api-sustainablesupply-scraper-cheap",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/data_api~sustainablesupply-scraper-cheap/runs": {
            "post": {
                "operationId": "runs-sync-data_api-sustainablesupply-scraper-cheap",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/data_api~sustainablesupply-scraper-cheap/run-sync": {
            "post": {
                "operationId": "run-sync-data_api-sustainablesupply-scraper-cheap",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "categoryUrls": {
                        "title": "Category page URLs",
                        "type": "array",
                        "description": "Paste one or more SustainableSupply.com collection or category pages here. Each link should open a product listing — for example a /collections/ page or a search-results page.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "searchTerms": {
                        "title": "Search keywords",
                        "type": "array",
                        "description": "Type plain keywords you want to look up on the store, such as 'paper towel' or 'safety glasses'. Each keyword runs as its own search. Use this on its own or together with category URLs.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "resultsPerSource": {
                        "title": "Products per URL or keyword",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "How many products to pull from each individual URL or keyword. The cap is counted per source, so two keywords set to 50 can return up to 100 products in one run.",
                        "default": 30
                    },
                    "timeoutSeconds": {
                        "title": "Request timeout (seconds)",
                        "minimum": 5,
                        "maximum": 120,
                        "type": "integer",
                        "description": "How long to wait on each request before it is dropped. Bump this higher when a slow connection produces timeout errors.",
                        "default": 45
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
