# Gathern Rental Listings Scraper (`bovi/gathern-scraper`) Actor

Collect public Gathern rental listings in Saudi Arabia without logging in. Get prices, capacity, ratings, locations, photos, and features. Run with a city or public search URL. Pricing: $0.00785 per saved listing plus $0.00005 per Actor Start event.

- **URL**: https://apify.com/bovi/gathern-scraper.md
- **Developed by:** [Vitalii Bondarev](https://apify.com/bovi) (community)
- **Categories:** Real estate, Travel, Automation
- **Features:** Limited permissions
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $7.85 / 1,000 gathern rental listings scrapers

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?

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

## Gathern Rental Listings Scraper

Collect public vacation-rental listings in Saudi Arabia from Gathern's search results and listing pages, no login needed. On the Free plan you pay $0.00005 per Actor Start event plus $0.00785 per saved rental listing.

- Get titles, rental types, nightly prices, service-inclusive totals, capacities, ratings, and review counts.
- Compare prices and availability across Riyadh, Jeddah, and other cities.
- Build location datasets with districts, coordinates, photos, and property features.
- Use descriptions, amenities, bedroom details, and cancellation fields for rental research and travel planning.

### What you get

Fields are saved only when Gathern provides a value. The Actor also calculates `price_per_guest_sar` when the nightly price and a positive capacity are available.

| Field or fields | Type | What it contains |
|---|---|---|
| `listingId`, `url`, `propertyTitle` | Integer; string | Listing ID, Gathern listing URL, and property title (always present) |
| `unit_type`, `unit_type_id` | String; integer | Rental category and its ID, such as apartment or chalet |
| `currency` | String | Listing currency; the Actor records `SAR` |
| `nightly_price`, `price_before_discount`, `total_price_with_services` | Number | Nightly, pre-discount, and service-inclusive prices as returned by Gathern |
| `price_per_guest_sar` | Number | Nightly price divided by capacity, rounded to two decimals |
| `capacity` | Integer | Guest capacity |
| `bedrooms`, `master_beds`, `single_beds`, `bathrooms` | Integer | Bedroom, bed, and bathroom counts |
| `area_sqm` | Number | Property area in square metres |
| `rating`, `reviews_count`, `booking_count`, `views_count` | Number; integer | Rating, reviews, bookings, and views |
| `city`, `city_ar`, `district`, `district_ar` | String | English and Arabic location names |
| `latitude`, `longitude` | Number | Geographic coordinates |
| `photos`, `thumbnail` | Array; string | Photo URLs and thumbnail URL |
| `features` | Array of strings | Property features and amenities |
| `description` | String | Listing description |
| `check_in`, `check_out` | String | Stay dates returned by Gathern |
| `available` | Boolean | Availability value returned by Gathern |
| `has_insurance`, `has_free_cancellation` | Boolean | Insurance and free-cancellation values |
| `scraped_at` | String | UTC timestamp for record creation |

### Sample output

Shortened by omitting minor fields; the values are copied exactly from one dataset record.

```json
{
  "listingId": 277640,
  "url": "https://gathern.co/link/view?id=277640",
  "propertyTitle": "Apartment with Living Room",
  "unit_type": "Apartment",
  "currency": "SAR",
  "nightly_price": 300,
  "price_before_discount": 300,
  "total_price_with_services": 378,
  "price_per_guest_sar": 150,
  "capacity": 2,
  "rating": 10,
  "reviews_count": 1,
  "city": "Riyadh",
  "district": "Al Ghadeer Dist.",
  "latitude": 24.77799890874,
  "longitude": 46.661205478135
}
```

### Pricing

This Actor charges per event.

| Event | When it applies | Price on the Free plan |
|---|---|---:|
| `apify-actor-start` | When the Actor starts running | $0.00005 per event |
| `apify-default-dataset-item` | One saved rental listing (one dataset item, all fields) | $0.00785 per event on the Free plan |

The number of Actor Start events depends on Actor memory, with a minimum of one. With one Actor Start event:

- Free plan, 50 results: `(50 × $0.00785) + $0.00005 = $0.39255`
- Free plan, 1,000 results: `(1,000 × $0.00785) + $0.00005 = $7.85005`
- Free plan, 10,000 results: `(10,000 × $0.00785) + $0.00005 = $78.50005`

The Apify Free plan includes $5 of monthly platform usage credit. With one Actor Start event, that covers exactly 636 saved results at these Free-plan event prices.

Platform usage (compute, Apify Proxy traffic including residential, storage) is included in the event prices and paid by the Actor developer, so buyers do not pay it separately.

### How to use

1. Set `searchMode` to `byCity` and list cities in `cities`, or set it to `bySearchUrl` and add public Gathern `/search` URLs in `searchUrls`.
2. Optionally set `unitType`, `checkIn`, `checkOut`, and `sort`. These apply to city searches only. `lang` (`en` or `ar`) applies to both modes.
3. Limit the run with `maxPages` (search pages per city or URL) and `maxResults` (unique listings saved across the run).
4. Leave `proxyConfiguration` at its default, Apify Proxy with the `RESIDENTIAL` group, the setup used for the sample above.
5. Export the dataset as JSON or CSV, or read it through the Apify dataset API. Use Apify Schedules to repeat the run.

Example input:

```json
{
  "searchMode": "byCity",
  "cities": ["Riyadh"],
  "unitType": "",
  "lang": "en",
  "maxResults": 10,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

### Input parameters

| Parameter | What it does | Default |
|---|---|---|
| `searchMode` | `byCity` or `bySearchUrl`. | `byCity` |
| `cities` | City names for city mode, in English or Arabic. | `["Riyadh"]` |
| `searchUrls` | Public Gathern search URLs for search-URL mode. | Not set |
| `unitType` | City-search rental category: `resort`, `chalet`, `istraha`, `farm`, `camp`, `apartment`, `villa`, `room`, `studio`, or `serviced-apartment`. Empty means all. | `""` |
| `checkIn`, `checkOut` | City-search dates in `YYYY-MM-DD` format. | Not set |
| `lang` | `en` or `ar` for text returned by Gathern. | `en` |
| `sort` | City-search order: `points`, `price`, `rate`, or `newest`. | `points` |
| `maxPages` | Search pages processed per city or URL, at least 1. | `20` |
| `maxResults` | Unique listings saved across the run, at least 1. | `50` |
| `proxyConfiguration` | Apify proxy settings. | Apify Proxy, `RESIDENTIAL` |

### Limits and edge cases

| Condition | What the buyer sees | What to do |
|---|---|---|
| `maxResults` is reached | The Actor stops saving listings. | Increase `maxResults` for a larger dataset. |
| `maxPages` is reached | Pagination stops for that city or URL even if more pages may exist. | Increase `maxPages`. |
| A search page returns no items, or the last source page is reached | Pagination stops for that target. | Check the city, URL, dates, and filters. |
| A search URL is not a public Gathern `/search` page | The URL is ignored and adds no listings. | Use a public Gathern search-results URL. |
| A URL contains unsupported search parameters | Those parameters are not passed to the search request. | Use filters the Gathern search URL supports. |
| Gathern does not provide a field value | That field is omitted from the record. | Do not expect every field on every record. |
| A search request fails | A warning is logged and that target stops; records already saved remain. | Review the input and proxy settings, then retry. |
| A listing-detail request fails | A warning is logged. The search result can still be saved, but detail fields may be missing; records without a listing ID or title are skipped. | Retry if you need detail fields. |
| The same listing appears in several targets | Duplicate listing IDs are skipped. | Use several targets freely; each listing is saved once. |

### FAQ

#### How much does it cost?

See the Pricing section: on the Free plan, 50 saved listings with one Actor Start event cost $0.39255.

#### Why did my run return no listings?

The Actor stops when a search response contains no items, and it ignores any URL that is not a public Gathern `/search` page. Check the city or URL, dates, rental type, and page limit.

#### What happens if a page fails?

A failed search request logs a warning and stops that target; saved records stay in the dataset. If a detail request fails, fields that come only from the detail response may be missing.

#### Is using Gathern data legal or allowed?

The Actor reads only public Gathern search data and listing details. Whether a particular use is legal or allowed depends on Gathern's terms and the law that applies to you; review both before using the data.

### Related actors

- [Airbnb Scraper — Listings, Prices, Ratings & Hosts](https://apify.com/bovi/airbnb-scraper) — related bovi Actor for Airbnb listings, prices, ratings, and hosts.
- [At Home Japan Rental Listings](https://apify.com/bovi/athome-scraper) — related bovi Actor for rental listings.
- [Chaves na Mão Property Listings](https://apify.com/bovi/chaves-scraper) — related bovi Actor for property listings.

# Actor input Schema

## `searchMode` (type: `string`):

Choose named cities or provide Gathern search URLs.

## `cities` (type: `array`):

City names in English or Arabic, such as Riyadh, Jeddah, or الرياض. Used in City names mode.

## `searchUrls` (type: `array`):

Public Gathern search result URLs. Their city, dates, categories, and filters are preserved.

## `unitType` (type: `string`):

Optional rental category for City names mode.

## `checkIn` (type: `string`):

Optional check-in date in YYYY-MM-DD form.

## `checkOut` (type: `string`):

Optional check-out date in YYYY-MM-DD form.

## `lang` (type: `string`):

Language for text returned by Gathern.

## `sort` (type: `string`):

Sort city searches by Gathern's points, price, rating, or newest order.

## `maxPages` (type: `integer`):

Stops pagination after this many search pages for each city or URL.

## `maxResults` (type: `integer`):

Maximum number of unique rental listings to save.

## `proxyConfiguration` (type: `object`):

Optional Apify proxy settings. Leave disabled or empty to connect directly.

## Actor input object example

```json
{
  "searchMode": "byCity",
  "cities": [
    "Riyadh",
    "Jeddah"
  ],
  "searchUrls": [
    "https://gathern.co/search?city=3&chalet_cats%5B%5D=2"
  ],
  "unitType": "",
  "checkIn": "2026-11-01",
  "checkOut": "2026-11-03",
  "lang": "en",
  "sort": "points",
  "maxPages": 20,
  "maxResults": 50,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

Dataset with the scraped records.

# 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 = {
    "searchMode": "byCity",
    "cities": [
        "Riyadh"
    ],
    "lang": "en",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("bovi/gathern-scraper").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 = {
    "searchMode": "byCity",
    "cities": ["Riyadh"],
    "lang": "en",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("bovi/gathern-scraper").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 '{
  "searchMode": "byCity",
  "cities": [
    "Riyadh"
  ],
  "lang": "en",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call bovi/gathern-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bovi/gathern-scraper"
        }
    }
}
```

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/pZxSXisssF6gut3K4/builds/GB0J3TkbdIVZVbiTI/openapi.json
