# SpotHero Parking Scraper (`automation-lab/spothero-parking-rates-availability`) Actor

Extract SpotHero parking facilities, live quoted rates, availability, locations, and booking URLs by destination and dates.

- **URL**: https://apify.com/automation-lab/spothero-parking-rates-availability.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $14.24 / 1,000 item extracteds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## SpotHero Parking Scraper

Collect public **SpotHero parking** facilities, date-specific quoted rates, availability, addresses, walking distance, amenities, ratings, and booking URLs.

Use the Actor for one-time parking comparisons or schedule the same input to build your own recurring market-monitoring history. Results are normalized into one dataset row per facility and quote, ready for spreadsheets, databases, dashboards, and code.

### What does SpotHero Parking Scraper do?

The Actor searches SpotHero by a US destination and local start/end date-time.

It resolves cities, addresses, airports, and venues through SpotHero's public destination search, then exports the parking options SpotHero returns for that booking window.

Each result includes:

- facility identity and operator;
- advertised price and total quoted price;
- current availability and available-space count when exposed;
- street address and coordinates;
- straight-line and walking distance;
- rating and review count;
- selected-rate amenities and restrictions;
- a date-specific SpotHero booking-flow URL;
- canonical source URL and collection timestamp.

The Actor reads public results only. It does not book parking, sign in, store payment details, or bypass private account access.

### Who is it for?

#### Parking operators and revenue teams

Compare publicly quoted parking prices near selected destinations and dates.

#### Travel and mobility analysts

Measure available facilities, distances, amenities, and date-specific rates around airports, venues, and downtown areas.

#### Market-research teams

Schedule repeated runs, store each dataset, and calculate price or availability changes in your own warehouse.

#### Developers and data engineers

Send normalized SpotHero records to Google Sheets, Airtable, a database, BI tools, webhooks, or another Apify Actor.

### Why use this SpotHero parking data workflow?

- **Date-specific quotes:** records describe the booking window you requested, not a generic facility page.
- **Advertised and total prices:** compare the displayed parking amount with the quote including disclosed fees.
- **Availability context:** keep available, unavailable, and available-space signals when SpotHero exposes them.
- **Destination resolution:** use readable places such as `LAX`, `Downtown Chicago, IL`, or `Los Angeles, CA`.
- **URL input route:** reuse a public SpotHero search or destination URL containing `starts` and `ends`.
- **Typed output:** avoid parsing raw pages or reverse-engineering nested source responses.
- **Bounded collection:** control total records and per-destination records for predictable jobs.

### What SpotHero data can I extract?

| Group | Fields |
| --- | --- |
| Search context | `searchDestination`, `searchLatitude`, `searchLongitude`, `searchStarts`, `searchEnds` |
| Facility | `facilityId`, `title`, `facilityType`, `operatorName` |
| Availability | `available`, `availableSpaces` |
| Quote | `advertisedPrice`, `totalPrice`, `currency`, `rateId`, `rateType` |
| Location | `address`, `city`, `state`, `postalCode`, `country`, `latitude`, `longitude` |
| Distance | `distanceMeters`, `walkingMeters`, `walkingMinutes` |
| Quality | `rating`, `ratingCount` |
| Features | `amenities`, `restrictions`, `covered`, `selfPark`, `valet`, `alwaysOpen` |
| Links and audit | `bookingUrl`, `sourceUrl`, `scrapedAt` |

A field can be `null` when SpotHero does not expose that value for a facility or unavailable quote. Arrays can be empty.

### How to get SpotHero parking rates

1. Open the Actor in Apify Console.
2. Add at least one object under **Destination and date searches**.
3. Enter a destination recognized by SpotHero.
4. Enter local ISO date-times such as `2026-09-04T10:00:00` and `2026-09-04T18:00:00`.
5. Choose whether unavailable facilities should be retained.
6. Set an overall `maxItems` limit.
7. Run the Actor and open the default dataset.
8. Export results as JSON, CSV, Excel, XML, or connect through the dataset API.

A minimal input is:

```json
{
  "searches": [
    {
      "destination": "Los Angeles, CA",
      "starts": "2026-09-04T10:00:00",
      "ends": "2026-09-04T18:00:00"
    }
  ],
  "maxItems": 10
}
```

### Input parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `searches` | array | — | Destination plus local `starts` and `ends`. |
| `startUrls` | array | — | Public `https://spothero.com` URLs with `starts` and `ends`; search URLs should include `search_string`. |
| `maxItems` | integer | `50` | Overall facility-record limit, from 1 to 1,000. |
| `maxItemsPerSearch` | integer | — | Optional per-destination cap for balanced multi-market runs. |
| `includeUnavailable` | boolean | `true` | Retain facilities SpotHero reports as unavailable. |
| `sortBy` | string | `relevance` | Order each loaded result batch by relevance, distance, or advertised price. |
| `maxDistanceMeters` | integer | — | Optional radius from 100 to 50,000 meters. |

Provide at least one `searches` item or one `startUrls` item. When both are present, the Actor processes both routes under the same limits.

Date-times are destination-local values. The end must be later than the start. SpotHero can adjust a selected rate's actual covered end time; `searchStarts` and `searchEnds` preserve the resolved requested window while the booking URL contains the selected quote's times.

### Search by a SpotHero URL

Use a public URL when a workflow already stores SpotHero searches:

```json
{
  "startUrls": [
    {
      "url": "https://spothero.com/search?search_string=LAX&starts=2026-09-04T10%3A00%3A00&ends=2026-09-05T10%3A00%3A00"
    }
  ],
  "sortBy": "distance",
  "maxItems": 8
}
```

Only HTTPS URLs on `spothero.com` are accepted. URLs must include `starts` and `ends`. Destination or city paths are resolved from their final path segment when `search_string` is absent.

### Output example

The default dataset contains records shaped like this real public LAX result:

```json
{
  "searchDestination": "LAX",
  "searchLatitude": 33.9398799446,
  "searchLongitude": -118.386214021,
  "searchStarts": "2026-09-04T10:00",
  "searchEnds": "2026-09-05T10:00",
  "facilityId": "4712",
  "title": "Airport Spectrum LAX - Covered Self Park",
  "facilityType": "lot",
  "operatorName": "Airport Spectrum",
  "available": true,
  "availableSpaces": 20,
  "advertisedPrice": 11.99,
  "totalPrice": 15.99,
  "currency": "USD",
  "rateId": "157138",
  "address": "5757 West Century Boulevard",
  "city": "Los Angeles",
  "state": "CA",
  "postalCode": "90045",
  "walkingMeters": 525,
  "rating": 4.5,
  "amenities": ["Self Park", "Garage - Covered"],
  "covered": true,
  "selfPark": true,
  "valet": false,
  "bookingUrl": "https://spothero.com/purchase/hourly?facility=4712&rid=157138&starts=...&ends=...",
  "sourceUrl": "https://spothero.com/destination/los-angeles/lax-airport-parking?starts=...&ends=...",
  "scrapedAt": "2026-08-28T06:15:00.000Z"
}
```

Prices are decimal currency amounts. SpotHero's source API represents them in cents; the Actor converts them to normal dollar values.

### How much does it cost to collect SpotHero parking facilities?

This Actor uses pay-per-event pricing:

- a one-time **Start** event costs **$0.005** per run;
- every saved facility uses one **Item processed** event;
- rejected, duplicate, empty, or failed records are not charged as items.

Current per-facility tiers are:

| Tier | Price per facility |
| --- | ---: |
| FREE | $0.027292 |
| BRONZE | $0.023732 |
| SILVER | $0.018511 |
| GOLD | $0.014239 |
| PLATINUM | $0.0094928 |
| DIAMOND | $0.006645 |

At BRONZE pricing, one facility costs about $0.028732 including the start, 10 facilities cost about $0.24232, and 100 facilities cost about $2.37820. Apify applies the tier associated with the user's plan; the Console price display is authoritative.

### Recurring parking rate monitoring

The Actor returns a current snapshot rather than maintaining history inside one run.

A practical monitoring workflow is:

1. save fixed destinations and representative booking windows in an Apify Task;
2. set `maxItemsPerSearch` so each market contributes records;
3. schedule the Task daily or weekly;
4. send each run's dataset to a warehouse;
5. join on `facilityId`, `searchDestination`, and the booking window;
6. calculate changes in `advertisedPrice`, `totalPrice`, `available`, or `availableSpaces`;
7. trigger your own alert when a business threshold is crossed.

This separation keeps the Actor's output portable and lets you choose the retention and alerting system.

### Spreadsheet and database integrations

#### Google Sheets or Excel

Export the dataset as CSV or Excel from Apify Console, or connect the run through Make or Zapier.

#### SQL warehouse

Store one row per facility snapshot. Use `scrapedAt` as collection time and `facilityId` as the source identity.

#### BI dashboard

Chart median `totalPrice` by destination, parking date, distance band, facility type, or amenity.

#### Webhooks

Attach a run-succeeded webhook and fetch `defaultDatasetId` to continue an automated pipeline.

### Run through the Apify API with cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~spothero-parking-rates-availability/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searches": [{
      "destination": "Downtown Chicago, IL",
      "starts": "2026-09-04T09:00:00",
      "ends": "2026-09-04T17:00:00"
    }],
    "maxItems": 20
  }'
```

Add `waitForFinish=300` when a synchronous workflow should wait for completion, then fetch items from the returned `defaultDatasetId`.

### Run with JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/spothero-parking-rates-availability').call({
  searches: [{
    destination: 'Downtown Chicago, IL',
    starts: '2026-09-04T09:00:00',
    ends: '2026-09-04T17:00:00',
  }],
  includeUnavailable: true,
  maxItems: 20,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Run with Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/spothero-parking-rates-availability').call(run_input={
    'searches': [{
        'destination': 'Los Angeles, CA',
        'starts': '2026-09-04T10:00:00',
        'ends': '2026-09-04T18:00:00',
    }],
    'sortBy': 'price',
    'maxItems': 10,
})

items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

### Use through MCP and AI agents

Add the Actor to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/spothero-parking-rates-availability"
```

#### Claude Desktop

Add this server to the Claude Desktop MCP configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/spothero-parking-rates-availability"
    }
  }
}
```

#### Cursor

Open Cursor's MCP settings and add the same `apify` server URL shown above.

#### VS Code

Add an HTTP MCP server named `apify` in VS Code or your MCP-compatible extension, using the same Actor-specific URL.

Example prompts:

- “Find up to 10 SpotHero parking options in downtown Los Angeles from 10 AM to 6 PM next Friday and compare total prices.”
- “Collect LAX parking availability for a 24-hour booking window and return covered self-park facilities.”
- “Run the same Chicago and Los Angeles inputs, then summarize price and availability differences.”

The calling agent must provide concrete ISO date-times accepted by the Actor.

### Limits and data freshness

- SpotHero focuses on supported US destinations; unrecognized destinations fail with a clear error.
- Quotes and availability can change after collection and can expire before booking.
- A booking URL is a handoff to SpotHero, not a reservation guarantee.
- The selected first rate is normalized for each facility; other rate variants can exist upstream.
- SpotHero can return a quote whose covered period extends beyond the requested end.
- Walking distance depends on the source's currently available routing estimate.
- `availableSpaces` is nullable because not every facility exposes an inventory count.
- The Actor follows at most 20 source pages per destination and never exceeds input limits.
- Direct public JSON requests are used. No paid proxy fallback is enabled.

### Responsible use and legality

Public availability does not remove your responsibility to use data lawfully.

- Review SpotHero's terms and applicable laws for your use case.
- Do not use the Actor to interfere with booking systems or source operations.
- Avoid excessive schedules and choose limits appropriate to the analysis.
- Do not infer sensitive personal information from parking activity.
- Respect trademarks; this independent Actor is not affiliated with or endorsed by SpotHero.
- Verify current price, availability, restrictions, and cancellation terms on SpotHero before making a purchase decision.

### Troubleshooting

#### “Provide at least one item in searches or startUrls”

Add a destination object or a valid public SpotHero URL. Empty input fails closed rather than creating a misleading zero-result run.

#### “SpotHero could not resolve destination”

Use a more specific US city, address, airport code, or venue name. For example, use `Los Angeles, CA` instead of a broad region.

#### Date-time validation failed

Use local ISO date-times such as `2026-09-04T10:00:00`. Ensure `ends` is later than `starts` and choose a bookable future window.

#### The dataset has fewer rows than expected

The destination can have fewer facilities for the selected time, `includeUnavailable` may be false, or the overall/per-search cap may have been reached.

#### A quote differs from the SpotHero page later

Parking prices and availability are dynamic. Compare `scrapedAt`, the requested dates, and the live booking page.

#### An upstream request failed

The Actor retries network errors, rate limits, and temporary server errors with bounded backoff. Stable input errors and unexpected response contracts fail the run so scheduled workflows can detect the problem.

### FAQ

#### Does this Actor book a parking spot?

No. It returns public data and booking-flow URLs. The user completes and verifies any transaction on SpotHero.

#### Does it provide historical prices?

Each run provides a current snapshot for the requested future window. Schedule runs and retain datasets to create history.

#### Can I search multiple destinations?

Yes. Add multiple `searches` entries and use `maxItemsPerSearch` to balance output across them.

#### Can I include unavailable parking?

Yes. `includeUnavailable` defaults to true because unavailable facilities are useful for market and inventory monitoring.

#### Are advertised and total prices the same?

Not always. `advertisedPrice` is the displayed parking amount; `totalPrice` includes fees disclosed in the returned quote.

#### Why can price fields be null?

An unavailable facility or upstream result may not contain a selectable rate. The facility can still be useful as an availability record.

#### Does it require a SpotHero login or proxy?

No. The implemented workflow uses anonymous public destination and search endpoints and does not enable a proxy fallback.

### Related Automation Lab Actors

This Actor is intentionally source-specific. There is currently no separate Automation Lab parking-market Actor that would add a genuine adjacent workflow, so this README does not add unrelated cross-links merely for promotion.

For a broader pipeline, combine the dataset with your preferred scheduling, storage, spreadsheet, or database integration on Apify.

### Support

When reporting a problem, include:

- the sanitized Actor input;
- the run URL;
- the destination and booking window;
- whether the destination produced no facilities or the run failed;
- one affected `facilityId` when available.

Do not include Apify tokens, payment details, account cookies, or other secrets.

# Actor input Schema

## `searches` (type: `array`):

One or more US destinations with local parking start and end date-times. Use city, address, airport, or venue names recognized by SpotHero.

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

Optional SpotHero URLs containing starts and ends. Search URLs should also contain search\_string; destination/city paths are resolved from their final path segment.

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

Maximum number of parking facility records saved across all searches.

## `maxItemsPerSearch` (type: `integer`):

Optional per-destination cap. Use it to keep multi-destination output balanced while maxItems remains the overall cap.

## `includeUnavailable` (type: `boolean`):

Include facilities SpotHero returns as unavailable, useful for availability monitoring.

## `sortBy` (type: `string`):

SpotHero result ordering.

## `maxDistanceMeters` (type: `integer`):

Optional search radius from 100 to 50,000 meters. Leave empty to use SpotHero's destination default.

## Actor input object example

```json
{
  "searches": [
    {
      "destination": "Los Angeles, CA",
      "starts": "2026-09-04T10:00:00",
      "ends": "2026-09-04T18:00:00"
    }
  ],
  "maxItems": 20,
  "includeUnavailable": true,
  "sortBy": "relevance"
}
```

# Actor output Schema

## `overview` (type: `string`):

Open the default dataset in the parking rates and availability view.

# 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 = {
    "searches": [
        {
            "destination": "Los Angeles, CA",
            "starts": "2026-09-04T10:00:00",
            "ends": "2026-09-04T18:00:00"
        }
    ],
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/spothero-parking-rates-availability").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 = {
    "searches": [{
            "destination": "Los Angeles, CA",
            "starts": "2026-09-04T10:00:00",
            "ends": "2026-09-04T18:00:00",
        }],
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/spothero-parking-rates-availability").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 '{
  "searches": [
    {
      "destination": "Los Angeles, CA",
      "starts": "2026-09-04T10:00:00",
      "ends": "2026-09-04T18:00:00"
    }
  ],
  "maxItems": 20
}' |
apify call automation-lab/spothero-parking-rates-availability --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/spothero-parking-rates-availability"
        }
    }
}

```

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/4yw8jxdexq5MJtXyP/builds/c6Ah6LwvrKJzwyhUk/openapi.json
