# Goldcar Car Rental Rates Scraper (Spain Airport Offices) (`steadfetch/goldcar-rate-extractor`) Actor

Goldcar rental prices per vehicle group and Spanish airport office, from the public availability feed: daily price, total price, mileage policy and pickup location. No login, no browser. 26 major Spanish airports by default; enable monitorChanges for daily price-change alerts.

- **URL**: https://apify.com/steadfetch/goldcar-rate-extractor.md
- **Developed by:** [Steadfetch](https://apify.com/steadfetch) (community)
- **Categories:** Travel, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 1,000 rate delivereds

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/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

## steadfetch/goldcar-rate-extractor

Tested daily. Last verified: 2026-10-30

Returns Goldcar car rental prices per vehicle group and Spanish airport office from the public Goldcar availability feed, as JSON. One item per bookable group and office, with the daily and total price, the mileage policy and the exact pickup/return window.

### What it does

- Queries the public, anonymous Goldcar availability feed (`goldcar.es`) for one or more Spanish airport offices (IATA codes such as `AGP`, `BCN`, `TFS`, `LPA`, `TJF`, `ACE`, `FUE`, `IBZ`, `MAH`, `PMI`, `ALC`, `VLC`, `MAD`, `SVQ`, `OVD`, `VLL`, `GVD`, `REU`, `XRY`, `KKL`, `VGO`, `GRO`, `LEI`, `BIO`, `ZAZ`, `IBB`).
- Returns one row per bookable vehicle group: `carGroup`, `pricePerDayEur`, `totalPriceEur`, `currency`, `mileagePolicy`, `pickupLocationIata`, `locationName`, `pickupDate`, `returnDate` and `scrapedAt`.
- Uses plain HTTP + JSON. No browser, no login, no paywall and no CAPTCHA bypass.
- Validates every row against the dataset schema before it reaches the dataset, so invalid prices are surfaced instead of published.
- Keeps a single anonymous session (one cookie jar) for the whole run and re-posts the search for each office, at one request per second per office.
- Keeps a daily price history in the Steadfetch S3 bucket (written by the scheduled routine only) and, with `monitorChanges` enabled, delivers price-change alerts to a separate `change-alerts` dataset.

### How to use

Run it from the Apify Console or with the CLI:

```bash
apify call steadfetch/goldcar-rate-extractor --input='{"pickupLocations":["AGP","MAD"],"pickupDate":"2026-11-07","returnDate":"2026-11-14"}'
```

Read the rows from the run's default dataset (JSON, CSV or the API).

#### Minimum input

```json
{ "pickupLocations": ["AGP"] }
```

With no dates the Actor uses a rolling window: pickup 14 days from today and a 7-day rental. With no `pickupLocations` it checks the twenty-six default Spanish airport offices (`AGP`, `BCN`, `TFS`, `LPA`, `TJF`, `ACE`, `FUE`, `IBZ`, `MAH`, `PMI`, `ALC`, `VLC`, `MAD`, `SVQ`, `OVD`, `VLL`, `GVD`, `REU`, `XRY`, `KKL`, `VGO`, `GRO`, `LEI`, `BIO`, `ZAZ`, `IBB`).

#### Input fields

| Field | Type | Required | Default | Description | Example |
| --- | --- | --- | --- | --- | --- |
| `pickupLocations` | array | No | twenty-six airports | Three-letter IATA codes of the Goldcar airport offices to query. | `["AGP","MAD"]` |
| `pickupDate` | string | No | today + 14 days | Rental start date in `YYYY-MM-DD` format. | `"2026-11-07"` |
| `returnDate` | string | No | pickup + 7 days | Rental end date in `YYYY-MM-DD`; after the pickup date and at most 60 days later. | `"2026-11-14"` |
| `maxLocations` | integer | No | `30` | Safety cap on how many offices are queried (1-50). | `10` |
| `monitorChanges` | boolean | No | `false` | When true, compares this run with yesterday's saved snapshot and delivers price-change alerts to the separate `change-alerts` dataset. | `true` |

### Output

#### Example output

```json
{
  "url": "https://www.goldcar.es/es-es/reservas/disponibilidad/#pickupplace/AGP/pickupdate/2026-11-07%2010:00/dropoffplace/AGP/dropoffdate/2026-11-14%2010:00/",
  "title": "Group AA - Mini - Malaga Airport",
  "scrapedAt": "2026-10-24T17:30:00.000Z",
  "pickupLocationIata": "AGP",
  "locationName": "Malaga Airport",
  "pickupDate": "2026-11-07",
  "returnDate": "2026-11-14",
  "carGroup": "Group AA - Mini",
  "pricePerDayEur": 4.0,
  "totalPriceEur": 28.0,
  "currency": "EUR",
  "depositEur": null,
  "mileagePolicy": "Unlimited"
}
```

#### Output fields

| Field | Type | Description |
| --- | --- | --- |
| `url` | string | Public Goldcar search page for the same office and dates (common envelope, required). |
| `title` | string | Vehicle group and office, for a quick scan. |
| `scrapedAt` | date-time | ISO 8601 UTC timestamp of the run (common envelope, required). |
| `pickupLocationIata` | string | Three-letter IATA code of the pickup office. |
| `locationName` | string | English name of the pickup office. |
| `pickupDate` | date | Rental start date. |
| `returnDate` | date | Rental end date. |
| `carGroup` | string | Goldcar group code plus vehicle category, for example `Group AA - Mini`. |
| `pricePerDayEur` | number | Displayed daily rate in euros. |
| `totalPriceEur` | number | Displayed total rate in euros for the whole window. |
| `currency` | string | Always `EUR` on the Spanish feed. |
| `depositEur` | number or null | Security deposit when published; the availability feed currently does not expose it, so it is `null`. |
| `mileagePolicy` | string or null | Published mileage policy, for example `Unlimited` or `150 km/day`. |

New fields are additive and required fields never change, so downstream code can rely on the envelope plus the rate fields above.

### Monitor price changes

Set `monitorChanges` to `true` to turn the Actor into a price monitor:

```json
{
  "pickupLocations": ["AGP", "MAD"],
  "pickupDate": "2026-11-07",
  "returnDate": "2026-11-14",
  "monitorChanges": true
}
```

The Actor reads yesterday's snapshot from the shared bucket, compares it with the current run and delivers one alert per change to the named **`change-alerts`** dataset. The default rates dataset and its schema never change, so existing integrations keep working.

Alert fields: `alertType` (`price-increased`, `price-decreased`, `new`, `disappeared`), `pickupLocationIata`, `carGroup`, `pickupDate`, `returnDate`, `previousPriceEur`, `currentPriceEur`, `changePercent`, `previousSnapshotDate`, plus the common `url` and `scrapedAt` envelope.

The alerts dataset is available in the run's storages as `change-alerts` (for example through `GET /v2/datasets/{datasetId}/items`). Alerts are additive to the run start event and are not charged as dataset items.

**Only the offices queried in this run are compared.** Yesterday's snapshot may cover more offices; the ones you did not request (or that could not be queried because of a transient error) are never reported as `disappeared`, so a run over a subset such as `["AGP"]` never raises false alarms for `BCN`, `MAD` or the rest. A requested office that answers with zero rates does still alert: its previous rates appear as `disappeared`.

**How the history works.** The scheduled routine saves one snapshot per UTC day under `actors/goldcar-rate-extractor/YYYY-MM-DD/rates.json`. Customer-triggered runs never write to the bucket (company rule D-33); they only read it. When no previous snapshot exists (first run, or a gap in the series) the Actor logs it and still delivers the rates. For a stable comparison across days, pin `pickupDate` and `returnDate`: with the rolling default window, every day queries a different rental window and the comparison keys change. The sample `price-change-monitor` task prefill pins a fixed window, so edit its dates to an upcoming window inside Goldcar's booking horizon before running or scheduling it; a past date is rejected by the source.

With `monitorChanges` off (the default) the Actor does not read the bucket, does not create the alerts dataset and behaves exactly as before.

### Pricing

Pay-per-event with the two synthetic platform events: `apify-actor-start` at 0.00005 USD per run (Apify-recommended default, includes the first 5 seconds of compute) and `apify-default-dataset-item` at **2.00 USD per 1,000 results** (0.002 USD per delivered rate). There is no custom per-item event and no `Actor.charge()` call, so users are never billed twice. Offices without availability and groups without a usable price are never delivered and never billed.

Measured cost per 1,000 results: about **0.011 USD** (local run of five offices: 53 rows, 15 HTTP requests, 39.7 s at 256 MB and 0.2 USD per GB-hour), so the price leaves about 99 % margin against the 0.20 USD cost target. Running all twenty-six defaults costs about 0.06 USD per 1,000 results.

**Works on the Apify free plan - about 2,499 results for the $5 monthly credit.**

### FAQ

**Does the Actor need a login or a paid subscription to Goldcar?** No. It uses the public anonymous availability feed; it never bypasses logins, paywalls or CAPTCHAs. If the source ever serves a CAPTCHA or a block page, the run stops and reports it.

**Which offices are supported?** Any Goldcar airport office whose IATA code is accepted by the public feed. The default list covers twenty-six major Spanish airports across the Canary Islands, Balearic Islands, and the mainland (`AGP`, `BCN`, `TFS`, `LPA`, `TJF`, `ACE`, `FUE`, `IBZ`, `MAH`, `PMI`, `ALC`, `VLC`, `MAD`, `SVQ`, `OVD`, `VLL`, `GVD`, `REU`, `XRY`, `KKL`, `VGO`, `GRO`, `LEI`, `BIO`, `ZAZ`, `IBB`).

**Can I compare offices?** Yes. Pass several IATA codes; each row carries `pickupLocationIata`, so you can group and compare prices across offices.

**Which price is returned?** The rate Goldcar displays for the group in the search results: `pricePerDayEur` and `totalPriceEur` for the requested window. Extra products and optional insurance are not added.

**When am I charged?** Once per run start (`apify-actor-start`) and once per result saved (`apify-default-dataset-item`). Failed runs that deliver no results only incur the start event.

**Is the output schema stable?** Yes. New fields are added additively and required fields never change.

**Can I request a new source?** Yes. Open an issue in the Steadfetch actors repository describing the public page you want tracked.

**Does the Actor save historical data?** Yes. The scheduled routine saves a daily snapshot to the shared S3 bucket (`actors/goldcar-rate-extractor/YYYY-MM-DD/rates.json`); customer-triggered runs never write to it. Set `monitorChanges: true` to compare against yesterday's snapshot and receive price-change alerts in the separate `change-alerts` dataset.

**Can I get price alerts without scraping twice?** Yes. One run with `monitorChanges: true` returns today's rates in the default dataset and the day-over-day changes in the `change-alerts` dataset.

### Support

Report bugs or request features through the Apify Store page (Issues tab) of the Actor, or through the Steadfetch actors repository issues. Include the run ID and the input used.

### Maintenance

This Actor is **tested daily**: the monorepo CI runs lint, typecheck, schema tests and the publish gate on every push, and the daily catalog QA runs the prefilled input against the live source. If the Goldcar feed changes shape, the output-schema validation fails the run instead of publishing bad data.

### Other Steadfetch Actors

- [TED Tender Monitor](https://apify.com/steadfetch/ted-tender-monitor) - EU public procurement notices.
- [SEC EDGAR Monitor](https://apify.com/steadfetch/sec-edgar-monitor) - US company filings.
- [Goldcar Car Rental Rates Scraper](https://apify.com/steadfetch/goldcar-rate-extractor) - Spanish airport car rental prices (this Actor).

# Actor input Schema

## `pickupLocations` (type: `array`):

Three-letter IATA codes of the Goldcar airport offices to query, for example \["AGP", "BCN", "TFS"]. Defaults to AGP, BCN, TFS, LPA, TJF, ACE, FUE, IBZ, MAH, PMI, ALC, VLC, MAD, SVQ, OVD, VLL, GVD, REU, XRY, KKL, VGO, GRO, LEI, BIO, ZAZ, IBB when omitted or empty.

## `pickupDate` (type: `string`):

Rental start date in YYYY-MM-DD format. Optional: defaults to 14 days from today so the sample input never expires.

## `returnDate` (type: `string`):

Rental end date in YYYY-MM-DD format; must be after pickupDate and at most 60 days later. Optional: defaults to 7 days after the pickup date.

## `maxLocations` (type: `integer`):

Safety cap on how many offices from pickupLocations are queried. Default 30, maximum 50.

## `monitorChanges` (type: `boolean`):

When true, reads yesterday's saved snapshot from the Steadfetch S3 bucket, compares it with this run and delivers price changes (increases, decreases, new and disappeared rates) to the separate "change-alerts" dataset. Customer runs only read the bucket; only the scheduled routine writes the daily snapshot. Pin pickupDate and returnDate so several days compare the same rental window.

## Actor input object example

```json
{
  "pickupLocations": [
    "AGP",
    "BCN",
    "TFS"
  ],
  "pickupDate": "2026-11-07",
  "returnDate": "2026-11-14",
  "maxLocations": 26,
  "monitorChanges": true
}
```

# Actor output Schema

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

Dataset items validated against the item schema in dataset_schema.json (fields).

# 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 = {
    "pickupLocations": [
        "AGP"
    ],
    "maxLocations": 30,
    "monitorChanges": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("steadfetch/goldcar-rate-extractor").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 = {
    "pickupLocations": ["AGP"],
    "maxLocations": 30,
    "monitorChanges": False,
}

# Run the Actor and wait for it to finish
run = client.actor("steadfetch/goldcar-rate-extractor").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 '{
  "pickupLocations": [
    "AGP"
  ],
  "maxLocations": 30,
  "monitorChanges": false
}' |
apify call steadfetch/goldcar-rate-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,steadfetch/goldcar-rate-extractor"
        }
    }
}
```

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/cLd6nfFVmvohmHHDo/builds/oao7xQ8lpELSOyaBV/openapi.json
