# Squarespace Commerce Product Price & Stock Monitor (`clintsa/squarespace-commerce-product-price-stock-monitor`) Actor

Extract per-product and per-variant prices, sale prices, SKUs, and exact stock from Squarespace storefronts.

- **URL**: https://apify.com/clintsa/squarespace-commerce-product-price-stock-monitor.md
- **Developed by:** [Andy Besos](https://apify.com/clintsa) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 66.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 price and stock rows

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

Turn public Squarespace Commerce catalogs into flat, analysis-ready product and variant rows. **Squarespace Commerce Product Price & Stock Monitor** reads each storefront's `/shop?format=json` collection and returns regular prices, active sale prices, SKUs, option values, exact tracked quantities, unlimited-inventory flags, and native update times.

You do not need a Squarespace account, Commerce API key, login cookie, browser, or proxy. The Actor uses direct HTTPS requests and only reads fields the storefront publishes in its page JSON.

### Why use this Squarespace Commerce scraper?

- **One row per product and variant:** join, filter, and compare SKUs without unpacking a nested variant array. `recordType` identifies each row and `recordId` stays stable across runs.
- **Stock without guesswork:** variant rows keep Squarespace's native `qtyInStock` and `unlimited` values as separate fields. `inStock` is derived from both signals rather than from page text.
- **Price fields built for comparison:** `price`, `salePrice`, and `effectivePrice` are numbers, while `currency` is a separate code. Product rows summarize the minimum variant price; variant rows retain the exact variant price.
- **Incremental and scheduled workflows:** filter by Squarespace's product-level `updatedOn` timestamp with `since`, or use the persistent Actor monitor to detect new, updated, and removed product or variant rows.
- **Direct, lightweight extraction:** no DOM selectors, browser startup, authentication, or proxy fees. Pagination is followed until the complete public collection has been captured.
- **Ready for downstream tools:** export the default Dataset as JSON, CSV, Excel, XML, or RSS, or connect it to the Apify API, schedules, webhooks, Make, Zapier, and client libraries.

Temporary `429` and server errors are retried with backoff. Each storefront is isolated, so one unavailable domain is logged without discarding successful results from the others. The run fails only if every requested storefront fails.

### Pricing

This Actor uses pay-per-event pricing: **$0.001 per run plus $0.003 per product or variant row**.

| Dataset rows | Actor event price |
| ---: | ---: |
| 1 | $0.004 |
| 100 | $0.301 |
| 1,000 | $3.001 |
| 10,000 | $30.001 |

A product with no variants produces one charged row. A product with five variants produces six charged rows: one product row and five variant rows. The `SUMMARY` record is stored separately in the key-value store and is not a Dataset row. Prices above cover the Actor's chargeable run and row events; standard Apify charges for retaining or downloading data after a run may apply.

### How to use this Actor

Add Squarespace storefront hostnames or URLs. These input forms are accepted and normalized to the hostname:

- `bgdbshop.squarespace.com`
- `https://mnbookarts.squarespace.com/shop`
- `https://mnbookarts.org/shop?category=Books`

The Actor always reads the normalized host's `/shop?format=json` collection. Paths, fragments, and query parameters in the submitted URL are not used as collection filters.

#### Quick, low-cost check

```json
{
  "storefronts": ["bgdbshop.squarespace.com"],
  "maxProductsPerStore": 1
}
```

The prefilled input uses this shape so the first run stays fast and returns at least one product row. The product limit counts products, not Dataset rows; all variants belonging to a selected product are included.

#### Compare several storefronts

```json
{
  "storefronts": [
    "mnbookarts.squarespace.com",
    "bgdbshop.squarespace.com"
  ],
  "maxProductsPerStore": 200,
  "requestDelayMillis": 500
}
```

Set `maxProductsPerStore` to `0` to export every product and variant row from every storefront. The Actor still reads complete pagination before applying an output limit, which keeps monitoring snapshots accurate.

#### Export products updated after a cutoff

```json
{
  "storefronts": ["bgdbshop.squarespace.com"],
  "since": "2026-08-01T00:00:00.000Z",
  "maxProductsPerStore": 0
}
```

`since` compares the cutoff with Squarespace's native product-level `updatedOn`. When a product passes the cutoff, its product row and every variant row are exported. Epoch milliseconds such as `1785542400000` are also accepted.

### Monitor new, updated, and removed rows

Every successful run stores a complete snapshot in a named key-value store. Run the Actor on a schedule with the same `monitorId` and storefronts to create a persistent product and variant change feed.

```json
{
  "storefronts": ["bgdbshop.squarespace.com"],
  "monitorId": "weekly-map-watch",
  "onlyChangesSince": "2026-08-01T00:00:00.000Z",
  "maxProductsPerStore": 0
}
```

The first run creates the baseline and labels every row `new`. Later runs compare price, stock, SKU, attributes, update time, and the other stable output fields:

| `changeType` | Meaning |
| --- | --- |
| `new` | The product or variant was absent from the previous successful snapshot. |
| `updated` | At least one monitored field changed; `changedFields` names each field. |
| `unchanged` | The row is still present and its monitored values match. |
| `removed` | A previously present product or variant disappeared from the complete public collection. |

`since` and `onlyChangesSince` answer different questions. Use `since` for the native Squarespace product update timestamp. Use `onlyChangesSince` for Actor-detected differences between complete snapshots, including removed variants. A removal is emitted once, on the run that first detects it.

### API example

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/Clintsa~squarespace-commerce-product-price-stock-monitor/run-sync-get-dataset-items" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "storefronts": ["bgdbshop.squarespace.com"],
    "maxProductsPerStore": 10
  }'
```

For a large catalog, start the run asynchronously and read the default Dataset after it succeeds.

### Input options

| Field | Type | What it controls |
| --- | --- | --- |
| `storefronts` | string array | Required Squarespace hostnames or URLs. |
| `maxProductsPerStore` | integer | Products exported per storefront, from 0 to 5,000; `0` means the full catalog. Variant rows belonging to selected products are included. |
| `since` | ISO timestamp or epoch milliseconds | Keeps products whose native `updatedOn` is newer than the cutoff. |
| `monitorId` | string | Persistent namespace for independent schedules and watchlists. |
| `onlyChangesSince` | ISO timestamp | Keeps Actor-detected new, updated, or removed rows first detected since this time. |
| `requestDelayMillis` | integer | Optional delay of 0–60,000 milliseconds between storefronts. |

### Output

Each Dataset item is a product or variant row. This abbreviated variant example shows the fields most useful for price and stock monitoring:

```json
{
  "recordType": "variant",
  "recordId": "variant:69189721dae239382cdc5896:7678f250-6f8d-4912-894f-d792b6ac8875",
  "storefront": "bgdbshop.squarespace.com",
  "sourceUrl": "https://bgdbshop.squarespace.com/shop?format=json",
  "productId": "69189721dae239382cdc5896",
  "variantId": "7678f250-6f8d-4912-894f-d792b6ac8875",
  "productUrl": "https://bgdbshop.squarespace.com/shop/p/spokessasstee",
  "productTitle": "2026 SPOKES AND SASS NATIONAL MEETUP TEE",
  "productType": "physical",
  "updatedOn": 1788110504661,
  "currency": "USD",
  "price": 29,
  "salePrice": 10,
  "effectivePrice": 10,
  "onSale": true,
  "sku": "SQ6105862",
  "attributes": { "Size": "XSmall" },
  "qtyInStock": 0,
  "unlimited": false,
  "inStock": false,
  "variantCount": 7,
  "changeType": "new",
  "changedFields": []
}
```

Product rows use the same shape with `variantId`, `sku`, and `attributes` set to null. Their price is the minimum variant price, and their stock quantity is the sum of tracked variants. If at least one variant is unlimited, `unlimited` is true and `inStock` is true. After every run, the `SUMMARY` key-value record reports requested, successful, and failed storefronts, fetched products, exported rows, change totals, filters, and completion time.

### Use cases

- Monitor your own Squarespace storefront prices and customer-visible inventory from outside the admin.
- Check MAP policy across authorized Squarespace retailers by joining variant SKUs and `effectivePrice`.
- Compare the same SKU across several storefronts without platform-specific HTML selectors.
- Feed product, sale-price, and stock rows into a warehouse, dashboard, spreadsheet, or alert workflow.
- Build a scheduled availability feed for dropshipping or catalog aggregation.
- Detect when a merchant adds, changes, or removes a product variant.

### FAQ

#### Do I need a Squarespace Commerce API key?

No. The Actor reads the public page JSON used by the storefront. It does not call private Commerce APIs or enter the Squarespace admin.

#### Does this Squarespace stock monitor use a browser or proxy?

No. It uses direct HTTPS JSON requests. There is no browser-rendering or proxy option in the input.

#### Does `qtyInStock` show exact variant inventory?

It returns the exact value publicly supplied by Squarespace. `unlimited: true` is kept separately because an unlimited variant does not have a meaningful finite quantity. A null value means the storefront did not publish that stock signal.

#### Can I monitor a Squarespace store on a custom domain?

Yes, if its public store collection is available at `/shop?format=json`. Submit the custom hostname or a full URL; the Actor normalizes it automatically.

#### Can I scrape several Squarespace storefronts in one run?

Yes. Add multiple entries to `storefronts`. Every row includes `storefront`, `productId`, and `recordId`, so results remain attributable and safe to join.

#### Why are there more rows than the product limit?

The limit counts products. Each selected product creates one product row and one additional row per public variant. This flat model is what makes SKU-level comparisons and stock alerts straightforward.

#### How fresh is `updatedOn`?

It is the native timestamp Squarespace publishes for the product record. The Actor reports it without inventing a refresh guarantee. For independent verification of any field change, use recurring runs with the same `monitorId`.

### Limitations and responsible use

- The storefront must expose its commerce collection at `/shop?format=json`; password-protected stores and private admin inventory are not accessed.
- The JSON formatter is public and documented for Squarespace template data, but Squarespace describes it as dynamic rather than a stable Commerce API. The response shape can change.
- `updatedOn` is product-level. Variant rows inherit their parent product's timestamp because the public payload does not provide a separate variant update time.
- Product-row stock is an aggregate convenience field. Use variant rows when exact SKU-level quantities matter.
- Public reachability does not itself grant permission. Squarespace-generated `robots.txt` files commonly disallow `?format=json`, and individual storefront terms may add restrictions. Use the Actor only for storefronts you own or are authorized to monitor, and comply with applicable law, robots instructions, and site terms.

### Support

Report a problem or request a field through the Issues tab on this Actor's page. Include the run ID, the affected storefront, and the input used; remove any secrets before posting.

# Actor input Schema

## `storefronts` (type: `array`):

Required. Squarespace storefront hostnames or URLs, such as `bgdbshop.squarespace.com`, `https://mnbookarts.org`, or `https://example.squarespace.com/shop`. Paths, queries, and trailing slashes are normalized to the storefront hostname.

## `maxProductsPerStore` (type: `integer`):

Maximum products exported per storefront. Every selected product produces one product row plus one row for each variant. Set to `0` for the full catalog; the prefill selects one product for a fast health check.

## `since` (type: `string`):

Optional Squarespace update cutoff as an ISO 8601 timestamp or epoch milliseconds. Only products whose native `updatedOn` is newer are exported, together with all of their variant rows.

## `monitorId` (type: `string`):

Persistent namespace for actor-side change tracking. Keep the same value for the same storefronts and filters; use another value for an independent schedule or watchlist.

## `onlyChangesSince` (type: `string`):

Optional ISO 8601 timestamp. Exports only product or variant rows the Actor detected as new, updated, or removed since that time. The first run creates the baseline.

## `requestDelayMillis` (type: `integer`):

Optional delay in milliseconds between storefronts. Direct requests already retry temporary errors with backoff; increase this only when a storefront asks for slower access.

## Actor input object example

```json
{
  "storefronts": [
    "mnbookarts.squarespace.com",
    "bgdbshop.squarespace.com"
  ],
  "maxProductsPerStore": 1,
  "monitorId": "default",
  "requestDelayMillis": 0
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `summary` (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 = {
    "storefronts": [
        "bgdbshop.squarespace.com"
    ],
    "maxProductsPerStore": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("clintsa/squarespace-commerce-product-price-stock-monitor").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 = {
    "storefronts": ["bgdbshop.squarespace.com"],
    "maxProductsPerStore": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("clintsa/squarespace-commerce-product-price-stock-monitor").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 '{
  "storefronts": [
    "bgdbshop.squarespace.com"
  ],
  "maxProductsPerStore": 1
}' |
apify call clintsa/squarespace-commerce-product-price-stock-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,clintsa/squarespace-commerce-product-price-stock-monitor"
        }
    }
}

```

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/Y7panfsvZZLmm1OCm/builds/LqXqxOfVveyS4yY3b/openapi.json
