# Apartments.com Reviews Scraper (`fetch_cat/apartments-scraper-api-scraper`) Actor

Export public Apartments.com property reviews for recurring reputation monitoring.

- **URL**: https://apify.com/fetch\_cat/apartments-scraper-api-scraper.md
- **Developed by:** [Hanna Nosova](https://apify.com/fetch_cat) (community)
- **Categories:** Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.24 / 1,000 item processeds

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?

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

## Apartments.com Reviews Scraper

This Apartments.com scraper exports public property reviews for recurring reputation monitoring. Provide direct property URLs and receive normalized, deduplicated Apartments.com data that is easy to compare across scheduled runs or use in an Apartments.com API workflow.

### Why use it

Property teams need a dependable snapshot of the public renter feedback shown on known Apartments.com property pages. This Actor turns those public review records into a dataset with a stable review ID, property context, ratings, dates, and source URLs.

Use it to:

- Monitor new renter feedback for a portfolio of known properties.
- Build property-level review snapshots for reporting and dashboards.
- Deduplicate reviews between scheduled exports with `reviewId`.
- Join review text to a property URL and aggregate-rating context.
- Export public review data to JSON, CSV, Excel, or another workflow.

### Who is it for?

Use this Actor when you already know the Apartments.com property pages that matter to your portfolio and want recurring public-review exports. It is suited to reputation teams, property managers, market researchers, and data teams that need review text with a clear property-level source.

### Input recipes

#### Monitor one property

```json
{
  "startUrls": [
    { "url": "https://www.apartments.com/presidential-towers-chicago-il/dsd9v8j/" }
  ],
  "maxItems": 10,
  "maxReviewsPerProperty": 10
}
```

#### Monitor several known properties

```json
{
  "startUrls": [
    { "url": "https://www.apartments.com/presidential-towers-chicago-il/dsd9v8j/" },
    { "url": "https://www.apartments.com/another-property-city-st/abc123/" }
  ],
  "maxItems": 20,
  "maxReviewsPerProperty": 10
}
```

Start with a low limit to confirm the targets, then increase `maxItems` when you need a larger snapshot.

### Input settings

| Input | Type | Description |
| --- | --- | --- |
| `startUrls` | array | Required direct public Apartments.com **property** URLs unless `resumeCheckpoint` is provided. Search URLs are not supported. |
| `resumeCheckpoint` | object | Optional schemaVersion 2 `PENDING_WORK` value copied from a partial prior run. It continues from the saved review position and IDs. |
| `maxItems` | integer | Global maximum number of review records across the original run and any resume. |
| `maxReviewsPerProperty` | integer | Maximum public review records saved for each property page. |

A URL is validated before collection. Use the canonical property detail page, not a city, category, or Apartments.com search page.

#### Resume a partial run without duplicate review charges

If a run ends with `status: "partial"`, copy its entire `PENDING_WORK` key-value value into `resumeCheckpoint` for the next run and keep the same limits. The checkpoint contains remaining URLs, the next review position, stable review IDs already saved, and the cumulative count. The resumed run skips those IDs, so it does not save or charge an `item` event for a review already saved by the interrupted run. A completed resume clears its `PENDING_WORK` record. The normal one-time `start` event applies to each new Actor run.

```json
{
  "resumeCheckpoint": {
    "schemaVersion": 2,
    "remainingPropertyUrls": ["https://www.apartments.com/presidential-towers-chicago-il/dsd9v8j/"],
    "currentPropertyUrl": "https://www.apartments.com/presidential-towers-chicago-il/dsd9v8j/",
    "nextReviewIndex": 1,
    "completedReviewIds": ["<64-character-review-id>"],
    "savedTotal": 1
  },
  "maxItems": 10,
  "maxReviewsPerProperty": 100
}
```

### Output

Each default-dataset item represents one public property review.

```json
{
  "reviewId": "b5d9…",
  "propertyName": "Example Property",
  "propertyUrl": "https://www.apartments.com/example/",
  "author": "Public reviewer",
  "title": "Great location",
  "body": "Public review text",
  "rating": 4,
  "datePublished": "2025-01-10",
  "language": "en",
  "aggregateRating": 4.2,
  "aggregateReviewCount": 120,
  "sourceUrl": "https://www.apartments.com/example/",
  "scrapedAt": "2026-09-05T00:00:00.000Z"
}
```

### Output fields

| Field | Description |
| --- | --- |
| `reviewId` | Stable SHA-256 identifier derived from the public review and property URL. |
| `propertyName` | Public property name. |
| `propertyUrl` | Public canonical property URL when supplied by the page. |
| `author` | Public review author, when supplied. |
| `title` | Public review title, when supplied. |
| `body` | Public review text. |
| `rating` | Public review rating, when supplied. |
| `datePublished` | Public review publication date, when supplied. |
| `language` | Public review language, when supplied. |
| `aggregateRating` | Public aggregate rating, when supplied. |
| `aggregateReviewCount` | Public aggregate review count, when supplied. |
| `sourceUrl` | Validated property URL requested in the run. |
| `scrapedAt` | ISO 8601 collection time. |

Some public pages omit optional author, title, language, or aggregate values. Those fields are nullable rather than guessed.

### Pricing

This Actor uses pay-per-event pricing: a small charge when a run starts and a charge for each public review saved. Higher Apify account tiers receive lower per-review prices. The configured limits let you keep each export within a predictable scope.

See the current rates on the [Pricing tab](https://apify.com/fetch_cat/apartments-scraper-api-scraper/pricing). You are charged only for the reviews saved to the dataset, in addition to the one-time run start event.

### Scheduling and comparison

Create an Apify task with the same property URLs and schedule it at the cadence your team needs. Compare `reviewId` values in each completed dataset to identify new public feedback without treating already-seen reviews as new records.

For portfolio reporting, preserve `propertyUrl`, `sourceUrl`, and `scrapedAt` alongside your own property identifiers. This keeps each review snapshot traceable to its requested public target and collection time.

### API usage

#### Node.js

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fetch_cat/apartments-scraper-api-scraper').call({
  startUrls: [{ url: 'https://www.apartments.com/presidential-towers-chicago-il/dsd9v8j/' }],
  maxItems: 10,
  maxReviewsPerProperty: 10,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("fetch_cat/apartments-scraper-api-scraper").call(run_input={
    "startUrls": [{"url": "https://www.apartments.com/presidential-towers-chicago-il/dsd9v8j/"}],
    "maxItems": 10,
    "maxReviewsPerProperty": 10,
})
print(list(client.dataset(run["defaultDatasetId"]).iterate_items()))
```

#### cURL

```bash
curl "https://api.apify.com/v2/acts/fetch_cat~apartments-scraper-api-scraper/runs?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"startUrls":[{"url":"https://www.apartments.com/presidential-towers-chicago-il/dsd9v8j/"}],"maxItems":10,"maxReviewsPerProperty":10}'
```

### MCP and AI agents

Add the Actor to an MCP-enabled workflow using [Apify MCP](https://mcp.apify.com?tools=fetch_cat/apartments-scraper-api-scraper). Give your agent direct property URLs and the same input limits shown above. Review the resulting dataset before using review text in downstream decisions.

For Claude Code, add the scoped tool server:

```bash
claude mcp add --transport http apify https://mcp.apify.com?tools=fetch_cat/apartments-scraper-api-scraper
```

Equivalent JSON configuration:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=fetch_cat/apartments-scraper-api-scraper"
    }
  }
}
```

Example prompts:

- “Collect up to 10 public reviews for this Apartments.com property URL.”
- “Run the Apartments.com reviews tool for these known properties and summarize new review IDs.”

### Limits

- Direct public Apartments.com property URLs are required.
- Search, discovery, and category URLs are not supported.
- The Actor does not access accounts, submit reviews, or claim exhaustive review history.
- A property page without public structured reviews can return no rows.
- A source block fails clearly instead of returning misleading empty data.

### FAQ

#### Why did my URL fail?

Use a direct public Apartments.com property page, not a search or category page.

#### Are all fields always present?

No. Optional public values such as author, title, rating, date, language, and aggregate values can be absent when the target page does not supply them.

#### How are duplicates handled?

`reviewId` is derived from the target property and public review content. A review is saved once per run, making scheduled snapshot comparison straightforward.

#### Can I schedule reputation monitoring?

Yes. Save a task with your property URLs, schedule it in Apify, and compare the next dataset with the previous one.

#### Can I run Apartments.com Reviews Scraper through an API, schedule, or MCP client?

Yes. The same JSON input works through Apify API clients, cURL, scheduled tasks, and the MCP tool link above.

#### What data can I export with apartments.com scraper?

Each saved row includes the public review text, property name and URL, review ID, available rating/date/language values, and aggregate rating context.

#### How much does it cost to use Apartments.com Reviews Scraper?

A small one-time run start charge applies, plus a per-review charge only for rows saved to the dataset. Check the Pricing tab for current tier rates.

#### What should I do if a page returns no reviews?

Confirm that the URL is a public property detail page and that reviews are currently visible on that property page. Keep the run ID when contacting support.

### Related Actors

- [Google Maps Reviews Scraper](https://apify.com/fetch_cat/google-maps-reviews-scraper)
- [Google Maps Places Scraper](https://apify.com/fetch_cat/google-maps-places-scraper)
- [Yelp Reviews Scraper](https://apify.com/fetch_cat/yelp-reviews-scraper)
- [Booking Reviews Scraper](https://apify.com/fetch_cat/booking-reviews-scraper)
- [Realtor.com Agents Scraper](https://apify.com/fetch_cat/realtor-com-agents-scraper)

### Support

For help, include the property URL (without private account data), run ID, and a short description of the unexpected result.

# Actor input Schema

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

Direct public Apartments.com property URLs to monitor. Required unless resuming from PENDING\_WORK.

## `resumeCheckpoint` (type: `object`):

Paste the schemaVersion 2 PENDING\_WORK value from a partial prior run. Do not combine with changed targets.

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

Global maximum review records across the original run and any resume.

## `maxReviewsPerProperty` (type: `integer`):

Maximum public reviews saved from each property page.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.apartments.com/presidential-towers-chicago-il/dsd9v8j/"
    }
  ],
  "maxItems": 10,
  "maxReviewsPerProperty": 100
}
```

# Actor output Schema

## `overview` (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 = {
    "startUrls": [
        {
            "url": "https://www.apartments.com/presidential-towers-chicago-il/dsd9v8j/"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fetch_cat/apartments-scraper-api-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 = { "startUrls": [{ "url": "https://www.apartments.com/presidential-towers-chicago-il/dsd9v8j/" }] }

# Run the Actor and wait for it to finish
run = client.actor("fetch_cat/apartments-scraper-api-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 '{
  "startUrls": [
    {
      "url": "https://www.apartments.com/presidential-towers-chicago-il/dsd9v8j/"
    }
  ]
}' |
apify call fetch_cat/apartments-scraper-api-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fetch_cat/apartments-scraper-api-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/4Ao7YkaomaC2Tnik9/builds/zkY2nwOE5ZBlS67ao/openapi.json
