# Redfin CSV and Excel Property Export Parser (`muhammadafzal/redfin-export-parser`) Actor

Normalize a Redfin property export you already have as CSV or XLSX. Filter, deduplicate, and preserve supplied columns; this Actor does not access Redfin.

- **URL**: https://apify.com/muhammadafzal/redfin-export-parser.md
- **Developed by:** [Muhammad Afzal](https://apify.com/muhammadafzal) (community)
- **Categories:** Real estate, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.008 / property export processed

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

## Redfin CSV and Excel Property Export Parser

This Actor normalizes a Redfin property export that you already have as CSV or XLSX. It reads the supplied file or pasted CSV, maps common property columns into a consistent dataset, applies optional filters, and preserves the original columns for review.

**It does not visit Redfin, query Redfin endpoints, or collect current listings.** Redfin's terms prohibit automated scraping without prior written permission. Use only files you are authorized to process. Redfin's download options depend on local MLS rules and its support guidance currently describes a 350-home export limit. See [Redfin's Terms of Use](https://www.redfin.com/about/terms-of-use) and [Redfin's download instructions](https://support.redfin.com/hc/en-us/articles/360016476931-Downloading-Data).

### Input

Supply exactly one of:

- **CSV or XLSX export file**: upload one file or provide a direct HTTPS file URL. Maximum 10 MB. The Actor follows at most five redirects, rejects Redfin hosts and private-network destinations, and accepts UTF-8 CSV or XLSX.
- **Pasted CSV text**: up to 250,000 characters. CSV, TSV, semicolon, and pipe delimiters are detected.

If both are supplied, the file takes priority. An empty or missing source is rejected with a message in the run log and `OUTPUT` summary. The file is never treated as a Redfin page to scrape.

The parser reads the first non-empty row as headers and the first visible non-empty worksheet in an XLSX workbook. It accepts up to 10,000 data rows and 500 columns. Filters are case-insensitive; a requested filter whose source column is missing is rejected instead of silently returning misleading results.

Useful recognized column names include address, city, state/province, ZIP/postal code, price, listing ID, listing URL, property type, status, beds/bedrooms, baths/bathrooms, living area, lot size, price per square foot, and days on market. Unrecognized columns remain in `sourceColumns` by default. Prices are labeled as USD by default; choose CAD or Unknown when appropriate. Currency is not converted.

The `recordId` is a SHA-256 fingerprint based on the available listing ID or URL, otherwise on the property facts. Deduplication is enabled by default. Every row is marked as `user_supplied_export`; this Actor does not verify the source, listing status, freshness, ownership, or data rights.

### Output

- **Default dataset**: one normalized property row per retained source row.
- **Key-value store `OUTPUT`**: status (`DATA`, `EMPTY`, `REJECTED`, `FAILED`, or `LIMIT_REACHED`), counts, filters, warnings, and event-charge count.

An export with no retained rows is a truthful empty result and does not incur the export-processing event. A free-plan run returns at most five property rows. Paid-plan runs can return up to `maxResults` (default 100, maximum 1,000).

### Pricing

Pay-per-event pricing charges one automatic Actor-start event per run and one `redfin-export-processed` event after a non-empty export has been written. Empty and rejected exports do not incur the processing event. Platform usage, if any, is separate from event prices.

| Tier | Start event | Export processed | Total for a non-empty export |
| --- | ---: | ---: | ---: |
| Free | $0.005 | $0.01000 | $0.01500 |
| Bronze | $0.005 | $0.00975 | $0.01475 |
| Silver | $0.005 | $0.00950 | $0.01450 |
| Gold | $0.005 | $0.00800 | $0.01300 |
| Platinum | $0.005 | $0.00800 | $0.01300 |
| Diamond | $0.005 | $0.00800 | $0.01300 |

Set a run's `maxTotalChargeUsd` high enough for the start fee and, when expecting rows, the applicable export event. At Free tier, that is at least $0.015 for a non-empty export. The automatic start event is never charged manually. An `OUTPUT` summary records the processing-event count.

### Example input

The sample rows below are fictional. Replace them with your own authorized export:

```json
{
  "csvContent": "ADDRESS,CITY,STATE,PRICE,PROPERTY TYPE,BEDS,BATHS,SQFT,STATUS\n1 Example Way,Sample City,CA,450000,Single-family,3,2,1450,For sale\n2 Demo Lane,Sample City,CA,625000,Condo,2,2,1100,For sale\n3 Fictional Road,Sample City,CA,390000,Single-family,2,1,980,Sold",
  "minPrice": 250000,
  "maxResults": 100,
  "deduplicate": true,
  "currencyCode": "USD"
}
```

To retain only condos, add `"propertyTypes": ["Condo"]`. To retain three-bedroom properties or larger, add `"minBedrooms": 3`.

### Privacy and access

The Actor does not request a Redfin proxy, log the file URL or pasted property rows, or send supplied records to a third-party extraction service. HTTPS file URLs are resolved and pinned to public IP addresses, redirects are revalidated, and local or private network destinations are rejected. Apify stores run inputs and outputs according to the platform's storage retention settings.

This Actor is private by default. It includes no Redfin logo, icon, or third-party branding.

# Actor input Schema

## `csvFile` (type: `array`):

Use this for a Redfin export file you downloaded and are authorized to process. Upload a CSV/XLSX file or provide a direct HTTPS file URL. Redfin page URLs are rejected; maximum file size is 10 MB. If both file and pasted text are supplied, this file takes priority.

## `csvContent` (type: `string`):

Use this for a small CSV export (up to 250,000 characters). Replace the fictional sample rows below with your own CSV; for XLSX or larger files, use CSV or XLSX export file instead. This Actor parses supplied text and makes no Redfin requests.

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

Use this to cap rows written after filters and deduplication. Enter an integer from 1 to 1,000; defaults to 100. Free-plan runs are capped at 5 delivered rows regardless of this value.

## `deduplicate` (type: `boolean`):

Use this to remove rows with the same listing ID or URL, or the same normalized property facts. Defaults to true. It does not merge records with different prices or statuses.

## `minPrice` (type: `number`):

Use this to keep rows at or above a numeric price, for example 250000. Requires a recognized price column; rows with no parseable price are excluded. Leave blank for no minimum.

## `maxPrice` (type: `number`):

Use this to keep rows at or below a numeric price, for example 750000. Requires a recognized price column; rows with no parseable price are excluded. Leave blank for no maximum.

## `minBedrooms` (type: `integer`):

Use this to keep homes with at least this many bedrooms, for example 3. Requires a recognized bedrooms column; rows with missing bedroom values are excluded. Leave blank for no bedroom filter.

## `propertyTypes` (type: `array`):

Use this to keep rows whose property-type text contains any value you enter, case-insensitively (for example Condo). Requires a recognized property type column. Leave empty for no property-type filter.

## `listingStatuses` (type: `array`):

Use this to keep rows whose status text contains any value you enter, case-insensitively (for example Sold). Requires a recognized status column. Leave empty for no status filter.

## `currencyCode` (type: `string`):

Use this to label numeric prices from the file. Choose CAD for a Redfin.ca export or Unknown if you do not know the currency. This setting does not convert prices.

## `includeSourceColumns` (type: `boolean`):

Use this to retain the supplied column names and values in each dataset item. Set false to return normalized fields only. Defaults to true so unrecognized export columns are not lost.

## Actor input object example

```json
{
  "csvContent": "ADDRESS,CITY,STATE,PRICE,PROPERTY TYPE,BEDS,BATHS,SQFT,STATUS\n1 Example Way,Sample City,CA,450000,Single-family,3,2,1450,For sale\n2 Demo Lane,Sample City,CA,625000,Condo,2,2,1100,For sale\n3 Fictional Road,Sample City,CA,390000,Single-family,2,1,980,Sold",
  "maxResults": 100,
  "deduplicate": true,
  "minPrice": 250000,
  "maxPrice": 750000,
  "minBedrooms": 3,
  "propertyTypes": [],
  "listingStatuses": [],
  "currencyCode": "USD",
  "includeSourceColumns": true
}
```

# Actor output Schema

## `records` (type: `string`):

One item for each retained row in the supplied CSV or XLSX file.

## `summary` (type: `string`):

Counts, applied filters, warnings, and whether the export-processing event was charged.

# 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 = {
    "csvContent": `ADDRESS,CITY,STATE,PRICE,PROPERTY TYPE,BEDS,BATHS,SQFT,STATUS
1 Example Way,Sample City,CA,450000,Single-family,3,2,1450,For sale
2 Demo Lane,Sample City,CA,625000,Condo,2,2,1100,For sale
3 Fictional Road,Sample City,CA,390000,Single-family,2,1,980,Sold`,
    "maxResults": 100,
    "deduplicate": true,
    "propertyTypes": [],
    "listingStatuses": [],
    "currencyCode": "USD",
    "includeSourceColumns": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("muhammadafzal/redfin-export-parser").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 = {
    "csvContent": """ADDRESS,CITY,STATE,PRICE,PROPERTY TYPE,BEDS,BATHS,SQFT,STATUS
1 Example Way,Sample City,CA,450000,Single-family,3,2,1450,For sale
2 Demo Lane,Sample City,CA,625000,Condo,2,2,1100,For sale
3 Fictional Road,Sample City,CA,390000,Single-family,2,1,980,Sold""",
    "maxResults": 100,
    "deduplicate": True,
    "propertyTypes": [],
    "listingStatuses": [],
    "currencyCode": "USD",
    "includeSourceColumns": True,
}

# Run the Actor and wait for it to finish
run = client.actor("muhammadafzal/redfin-export-parser").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 '{
  "csvContent": "ADDRESS,CITY,STATE,PRICE,PROPERTY TYPE,BEDS,BATHS,SQFT,STATUS\\n1 Example Way,Sample City,CA,450000,Single-family,3,2,1450,For sale\\n2 Demo Lane,Sample City,CA,625000,Condo,2,2,1100,For sale\\n3 Fictional Road,Sample City,CA,390000,Single-family,2,1,980,Sold",
  "maxResults": 100,
  "deduplicate": true,
  "propertyTypes": [],
  "listingStatuses": [],
  "currencyCode": "USD",
  "includeSourceColumns": true
}' |
apify call muhammadafzal/redfin-export-parser --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,muhammadafzal/redfin-export-parser"
        }
    }
}
```

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/LDeCV1QZFwTfoIoq5/builds/D2lUeYfaG2No7HcJ9/openapi.json
