# UK Self-Storage Price & Offer Monitor (`nerolabs/uk-storage-price-monitor`) Actor

Watch UK self-storage locations (Big Yellow and Shurgard) for price and current-offer changes, so you catch a deal or a price move the moment it happens. Shurgard results include the full per-unit-size price table.

- **URL**: https://apify.com/nerolabs/uk-storage-price-monitor.md
- **Developed by:** [Adam Pearce](https://apify.com/nerolabs) (community)
- **Categories:** Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#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

### What does UK Self-Storage Price & Offer Monitor do?

**UK Self-Storage Price & Offer Monitor** watches individual UK self-storage location pages, currently [Big Yellow](https://www.bigyellow.co.uk) and [Shurgard](https://www.shurgard.com), for their weekly price and current promotional offers, so you catch a price move or a new deal the moment it happens instead of re-checking the site by hand. Give it one or more store page URLs, turn on **Monitor mode**, and it remembers what it last saw and only tells you what actually changed.

Runs on Apify's infrastructure, so it's schedulable (daily, weekly, whatever fits), API-accessible, and works as a tool inside AI agents via Apify's MCP server. No account, no login required to use it.

### Why use UK Self-Storage Price & Offer Monitor?

Self-storage pricing moves with demand: operators run rotating promotions and adjust rates by location and season. Nobody wants to open a dozen store pages every week to see if anything's changed.

- **People planning a move or renovation**: watch your local store's price and offers so you book at the cheapest point, not whatever it happened to say the day you looked.
- **Removals and relocation businesses**: check a new customer's nearest store on demand, or watch a shortlist of stores across a region for ongoing client work.
- **Price comparison sites and deal-alert services**: pull live prices and offers as structured data instead of screen-scraping by hand.
- **Storage brokers and space-finder tools**: keep a portfolio of stores current without a person checking each one.

### How to use UK Self-Storage Price & Offer Monitor

1. Click **Try for free** and open the Input tab.
2. Find your store's page on [bigyellow.co.uk](https://www.bigyellow.co.uk) or [shurgard.com](https://www.shurgard.com) and paste its URL into **Store page URL** for a single check, or **Store page URLs** for several at once.
3. Leave **Monitor mode** off for a one-time snapshot, or turn it on and give your watchlist a stable **Watchlist ID** to only get charged the full rate when something actually changed.
4. Run it. Results land in the dataset, downloadable as JSON, CSV, or Excel, or pulled via the API.
5. Schedule it (Apify's built-in Scheduler) to run daily or weekly and get a running record of what moved.

### Input

| Field | Description |
|---|---|
| `storeUrl` | One store page URL, for a single one-off check. |
| `storeUrls` | A list of store page URLs to check. Required for Monitor mode (that's what gives each location a stable identity to track over time). |
| `monitorMode` | Off: a one-time snapshot. On: remembers your last check per store and only flags real changes. |
| `watchlistId` | A name for this watchlist, so it doesn't get mixed up with any other list you run. |

Currently supports **Big Yellow** (bigyellow.co.uk) and **Shurgard** (shurgard.com) store pages. More UK operators get added as their site structure is verified; a URL from an unsupported operator is reported honestly and never charged.

### Output

Big Yellow only publishes one headline price per store, so that's what you get for it. Shurgard genuinely publishes a full price table, every unit size at that store, so its results carry a `units` array too:

```json
{
  "storeUrl": "https://www.shurgard.com/en-gb/self-storage-uk/london/chiswick",
  "operator": "shurgard",
  "storeName": "Chiswick",
  "headlinePriceGbp": 10.62,
  "headlineUnitLabel": "15 sq ft",
  "headlinePriceRaw": "Chiswick storage from £10.62 per week for a 15 sq ft unit",
  "offers": [],
  "units": [
    { "sizeLabel": "15 sq ft", "priceGbp": 10.62, "standardPriceGbp": 21.00, "isSpecialPrice": true },
    { "sizeLabel": "30 sq ft", "priceGbp": 17.77, "standardPriceGbp": 35.54, "isSpecialPrice": true },
    { "sizeLabel": "40 sq ft", "priceGbp": 19.38, "standardPriceGbp": 38.77, "isSpecialPrice": true },
    { "sizeLabel": "50 sq ft", "priceGbp": 22.62, "standardPriceGbp": 45.23, "isSpecialPrice": true },
    { "sizeLabel": "65 sq ft", "priceGbp": 33.00, "standardPriceGbp": 65.54, "isSpecialPrice": true }
  ],
  "notFound": false,
  "parseIssue": null,
  "monitorMode": true,
  "isFirstCheck": false,
  "changeDetected": true,
  "changeSummary": "\"30 sq ft\" unit price changed from £15.00 to £17.77 per week.",
  "changes": ["\"30 sq ft\" unit price changed from £15.00 to £17.77 per week."],
  "checkedAt": "2026-08-14T12:07:04.235Z"
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

#### Data table

| Field | Meaning |
|---|---|
| `headlinePriceGbp` / `headlineUnitLabel` | The store's cheapest advertised weekly price and which unit size it's for. For Shurgard this is just the cheapest row of `units`; for Big Yellow it's the only price the operator publishes. |
| `units` | The full per-unit-size price table, when the source publishes one (Shurgard). `priceGbp` is the current rate, `standardPriceGbp` the non-discounted rate when the operator shows one separately, `isSpecialPrice` whether a promotional rate currently applies. Empty for operators that only expose one headline price. |
| `offers` | Current promotional offers listed as separate text (Big Yellow's style), e.g. "50% off for up to 8 weeks". Shurgard folds its promotions into the per-unit `isSpecialPrice` flag instead, so this is empty for Shurgard results. |
| `notFound` | `true` if the store page no longer exists (renamed, closed, or a wrong URL). |
| `parseIssue` | Set (and nothing charged) if the page loaded but this actor couldn't confidently read a price off it, e.g. the store currently has no listed availability. |
| `changeDetected` | Monitor mode only: any price moved (headline or a specific unit size), an offer or promotional rate started or ended, or a unit size was added or stopped being listed. |
| `changeSummary` | Plain-English description of what changed, if anything. |

### Pricing

Pay-per-event, you only pay for real answers:

- **$0.10** per one-time store check.
- **$0.35** per Monitor mode check where something actually changed: a price moved (headline or any specific unit size), an offer or promotional rate started or ended, or a unit size was added or removed.
- **$0.10** per Monitor mode check that confirms nothing changed.

That last number is intentionally close to the lookup price rather than near-free. This actor reads a real page through a real browser and a residential proxy on every single check, changed or not, so the cost of confirming "nothing changed" is genuinely close to the cost of a fresh lookup, not close to zero the way it would be for a plain API call.

Watching 10 stores daily in Monitor mode for a month, if nothing ever changed, runs about **$30**. In practice, prices and offers do move, and each real change costs $0.35 instead of $0.10, so a typical month lands somewhere in between depending on how much actually moves.

### Tips

- Give a watchlist a stable `watchlistId` and keep reusing it, that's what makes Monitor mode compare against your actual last check instead of starting fresh every time.
- Weekly scheduling is enough for most stores; daily suits a store you're actively deciding on.
- Want a real per-size price comparison? Use Shurgard store URLs and read the `units` array, that's genuinely public data on their pages. Big Yellow only ever publishes its one cheapest headline price; the full per-unit-size table there sits behind their own quote tool (postcode and move-in date), which this actor doesn't touch.

### FAQ

**Is this legal?** Reading a public store page is not illegal. This tool doesn't log in, doesn't bypass any paywall or quote flow, and only reads what's already publicly visible on the page. No scraping or automated-access prohibition was found on either operator's site (in both cases the only terms published are a storage-rental contract governing renting a unit, not a general website-use restriction), and robots.txt on both only disallows paths this actor doesn't touch.

**Why did a check come back with no data and no charge?** Both operators' sites can occasionally block or delay an automated request. This actor handles it automatically with a real browser and a settle wait before reading the page; if a check still comes back blocked after every retry, it reports that honestly instead of guessing, and you're not charged for it.

**Why is `units` empty for a Big Yellow result?** Big Yellow only ever publishes one headline price per store in plain page content; the full per-size table sits behind their quote tool, which this actor doesn't touch (see Tips above). This isn't a parsing gap, it's the honest limit of what's actually public there. Shurgard happens to publish its full table, so those results carry it.

**Which operators are supported, and will more be added?** Big Yellow and Shurgard today. Safestore and Storage King were checked and aren't addable yet (quote-gated pricing, or the site rejects the request outright); more operators get added as their pages are verified to publish a real, readable price.

Found a bug or have a request? Use the **Issues** tab, it's read personally, not a support bot.

# Actor input Schema

## `storeUrl` (type: `string`):

The full URL of one storage location's page on a supported operator's website (Big Yellow or Shurgard). Use this for a single one-off check.

## `storeUrls` (type: `array`):

A list of storage location page URLs to check. Required for Monitor mode (that's what gives each location a stable identity to track over time). Also the fastest way to check many known locations in one run. Currently supported operators: Big Yellow (bigyellow.co.uk) and Shurgard (shurgard.com). More UK operators are added as their site structure is verified.

## `monitorMode` (type: `boolean`):

When true, the Actor remembers each location's headline price and current offers from the last run and reports only what changed: the starting weekly price moving, or an offer being added or removed. Returns a cheap no-change confirmation otherwise. Schedule this Actor to run daily with the same storeUrls and watchlistId for ongoing monitoring. Requires storeUrl and/or storeUrls.

## `watchlistId` (type: `string`):

Only needed if you're running more than one independent monitored watchlist from the same Apify account (e.g. one per client or region) and want their change history kept separate. Leave as default otherwise.

## Actor input object example

```json
{
  "storeUrl": "https://www.bigyellow.co.uk/new-cross-self-storage-units",
  "storeUrls": [],
  "monitorMode": false,
  "watchlistId": "default"
}
```

# Actor output Schema

## `dataset` (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 = {
    "storeUrl": "https://www.bigyellow.co.uk/new-cross-self-storage-units"
};

// Run the Actor and wait for it to finish
const run = await client.actor("nerolabs/uk-storage-price-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 = { "storeUrl": "https://www.bigyellow.co.uk/new-cross-self-storage-units" }

# Run the Actor and wait for it to finish
run = client.actor("nerolabs/uk-storage-price-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 '{
  "storeUrl": "https://www.bigyellow.co.uk/new-cross-self-storage-units"
}' |
apify call nerolabs/uk-storage-price-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nerolabs/uk-storage-price-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/pDnsuawnV2ezdsl4J/builds/2UJzdbOhRUJmKH7kl/openapi.json
