# Facebook Marketplace Scraper + Seller Ratings & Alerts (`kingly_contest_7cb/facebook-marketplace-scraper`) Actor

Scrape Facebook Marketplace without login: full description, all photos, condition, location and seller name, join date and rating. Search any city, ZIP or coordinates with price, radius, condition and date filters. Monitoring mode returns only new and price-changed listings.

- **URL**: https://apify.com/kingly_contest_7cb/facebook-marketplace-scraper.md
- **Developed by:** [Carina Hatton](https://apify.com/kingly_contest_7cb) (community)
- **Categories:** E-commerce, Lead generation, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 listings

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

## Facebook Marketplace Scraper: listings, seller ratings, and new-listing alerts (no login)

Scrape Facebook Marketplace search results and listing pages **without logging in or providing cookies**. Each listing includes its full description, all photos, condition, category, approximate coordinates, distance from your search center, and **seller details**: name, ID, profile photo, join date, and rating. Search by keyword around any US city, ZIP code, or exact coordinates, filter by price, radius, condition, date listed, and delivery method, and turn on **monitoring mode** to get only the listings that are new or changed price since your last run.

### What you can use it for

- **Resellers and flippers**: get alerts for underpriced items minutes after they're posted.
- **Price research**: compare local asking prices by condition, location, and date.
- **Car dealers and buyers**: vehicle listings include any vehicle fields Facebook exposes.
- **Lead generation and market research**: see which sellers are active, how long they've been on Facebook, and their ratings.

### Features

| | |
|---|---|
| No login or cookies | Runs logged out over residential proxies, so your Facebook account is never at risk. |
| Seller info | Name and ID for every listing. With details turned on, you also get profile photo, join date, seller rating average and count, and business and verified flags. |
| Full details | Description, all photos (with sizes), condition, attributes, category, coordinates, listing status, and shipping. |
| Location that works | Accepts "City, ST", a ZIP code, or latitude/longitude, which are converted to exact coordinates. Facebook location slugs from URLs (`dallas`, `nyc`) also work. Radius can be in miles or km. |
| Filters | Price range, radius, condition, date listed (24h/7d/30d), local pickup or shipping, and sort order. Facebook applies these on its side. |
| Strict filtering | Facebook mixes in out-of-range items. The Actor drops results outside your price, radius, or condition, and sold or pending items. You can also add exclude keywords. |
| Monitoring mode | Seen listing IDs are kept in a **named key-value store**, so each scheduled run returns only `NEW` listings, plus `PRICE_CHANGED` listings with `previousPrice`. Already-seen listings are skipped *before* detail pages are opened, so you don't pay for them again. |
| Pagination | Uses Facebook's own pagination to go past the first page, up to your `maxItems` or `maxPagesPerSearch`. |
| Reliability | Uses a sticky residential session per search and rotates to a new IP and fresh cookies on any block. Retries use exponential backoff, and errors explain what to change. |

### Quick start

```json
{
  "searchQueries": ["mountain bike"],
  "location": "Dallas, TX",
  "radius": 25,
  "minPrice": 50,
  "maxPrice": 400,
  "sortBy": "creation_time_descend",
  "maxItems": 50,
  "includeDetails": true
}
```

#### Monitoring (new listings only)

1. Set `monitoringMode: true`, `sortBy: "creation_time_descend"`, and a `monitoringKey` such as `"dallas-bikes"`.
2. Schedule the Actor (for example, every 30 minutes) in **Schedules**.
3. Add an integration (Slack, email, a webhook, Make, or Zapier) on **Run succeeded**. On the first run, every listing is new and becomes the baseline. After that, you only receive new listings and listings whose price changed.

Seen IDs are stored in the key-value store `monitoringStoreName` (default `fb-marketplace-monitor`) under the key `SEEN-<monitoringKey>`. To reset a watch, delete that record. Listings that haven't appeared for `monitoringRetentionDays` are forgotten.

### Input

| Field | Description |
|---|---|
| `searchQueries` | Keywords. Each one is a separate search. |
| `startUrls` | Marketplace search, category, or item URLs. Filters in the URL are kept. |
| `location` / `latitude` + `longitude` | The search center. |
| `radius`, `radiusUnit` | Search radius in miles (the default unit) or km. |
| `minPrice`, `maxPrice` | Price range in whole currency units. |
| `conditions` | Any of `new`, `used_like_new`, `used_good`, `used_fair`. |
| `daysSinceListed` | `any`, `1`, `7`, or `30`. |
| `deliveryMethod` | `all`, `local_pickup`, or `shipping`. |
| `sortBy` | `best_match`, `creation_time_descend`, `price_ascend`, `price_descend`, or `distance_ascend`. |
| `maxItems`, `maxPagesPerSearch` | Limits per search. |
| `includeDetails` | Open each listing to get the full description, photos, and seller ratings (default `true`). |
| `strictFiltering`, `includeSold`, `excludeKeywords`, `requireKeywordsInTitle` | Clean-up options for the results. |
| `monitoringMode`, `monitoringStoreName`, `monitoringKey`, `emitPriceChanges`, `monitoringRetentionDays` | Monitoring settings. |
| `proxyConfiguration` | Proxy settings. Residential US is the default and is recommended. |

### Output example

```json
{
  "id": "1234567890123456",
  "url": "https://www.facebook.com/marketplace/item/1234567890123456/",
  "title": "26\" Schwinn mountain bike",
  "price": 60, "priceFormatted": "$60", "currency": "USD",
  "condition": "Used - Good", "conditionCode": "used_good",
  "description": "21-speed. Good working condition. Pickup only.",
  "photos": [{ "url": "https://scontent.example.fbcdn.net/photo.jpg", "width": 960, "height": 720 }],
  "photoCount": 5,
  "locationText": "Example City, TX", "latitude": 33.1, "longitude": -96.8, "distanceKm": 21.5,
  "createdAt": "2026-10-30T18:15:37.000Z",
  "categoryName": "Bicycles",
  "deliveryTypes": ["IN_PERSON"],
  "seller": {
    "id": "pfbid0EXAMPLE", "name": "Jane Doe",
    "joinedAt": "2015-05-01T00:00:00.000Z",
    "ratingAverage": 4.8, "ratingCount": 48,
    "isBusiness": false, "isVerified": false
  },
  "monitoringStatus": "NEW", "previousPrice": null,
  "detailsScraped": true
}
```

The dataset has an **Overview** table (photo, title, price, condition, location, distance, date, seller, rating) and a **Sellers** view. The `RUN-STATS` record in the default key-value store shows requests, retries, pages, and counts of filtered and skipped listings.

### Pricing

This Actor is pay-per-event, so you only pay for listings you get:

| What you get | Price |
|---|---|
| Each listing (title, price, location, photo, status, seller name and ID) | $1.50 per 1,000 |
| Add-on when `includeDetails` is on (description, all photos, condition, coordinates, seller join date and rating) | $3.50 per 1,000 |
| **Detailed listing total** | **$5.00 per 1,000** |

In monitoring mode, listings you've already seen aren't charged again. Set **Maximum cost per run** and the Actor stops cleanly when it reaches the limit.

### Tips and limits

- Facebook shows a limited number of results per search. For big areas, split the search by price bands or by several nearby locations.
- With `includeDetails: false`, you pay $1.50 per 1,000 instead of $5.00 and still get title, price, city, photo, date, and seller name and ID.
- `distanceKm`, the radius check, and condition checks need details, because search cards don't include coordinates or condition.
- Seller contact details (phone, email) are not public, so they're not included.
- Use the data responsibly and in line with Facebook's terms and local privacy laws. Seller names and photos are personal data, so only process them if you have a legitimate reason.

### FAQ

**Do I need a Facebook account?** No. Cookies are optional, and we don't recommend providing them.
**Why did a run return 0 results in monitoring mode?** Nothing new was posted since the last run. The status message says so.
**Can I scrape a list of item URLs?** Yes. Put the item URLs in `startUrls`.

# Actor input Schema

## `searchQueries` (type: `array`):

One or more keywords to search, for example "road bike" or "iphone 15". Each keyword is a separate search.

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

Optional. Paste Facebook Marketplace search, category, or item URLs (for example https://www.facebook.com/marketplace/dallas/search/?query=bike). Filters in the URL are kept.

## `location` (type: `string`):

City and state ("Austin, TX"), US ZIP code ("78701"), or a Facebook location slug or ID from a Marketplace URL ("dallas", "nyc", "108424279189115"). City names and ZIP codes are converted to exact coordinates.

## `latitude` (type: `string`):

Optional. Exact search center latitude, for example 32.7767. If you set this and Longitude, they take priority over Location.

## `longitude` (type: `string`):

Optional. Exact search center longitude, for example -96.7970.

## `radius` (type: `integer`):

How far from the location to search. Leave empty to use Facebook's default (about 40 miles).

## `radiusUnit` (type: `string`):

Unit for Search radius.

## `minPrice` (type: `integer`):

Minimum price in whole currency units, for example 50 for $50.

## `maxPrice` (type: `integer`):

Maximum price in whole currency units.

## `conditions` (type: `array`):

Only return items in these conditions. Leave empty for all conditions.

## `daysSinceListed` (type: `string`):

Only return listings posted within this window.

## `deliveryMethod` (type: `string`):

Filter by local pickup or shipping.

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

Sort order. For monitoring new listings, use "Date listed: newest first".

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

Stop each search after this many listings are output.

## `maxPagesPerSearch` (type: `integer`):

Safety limit on pages per search. Each page has about 24 listings.

## `includeDetails` (type: `boolean`):

Open each listing for the full description, all photos, condition, exact coordinates, category, and seller details (join date and ratings). Turn this off for faster, cheaper runs that only return search-card data, which still includes seller name and ID.

## `detailsConcurrency` (type: `integer`):

How many listing pages to open in parallel.

## `strictFiltering` (type: `boolean`):

Facebook often mixes in listings outside your filters. When this is on, the Actor removes items outside your price range, radius (when coordinates are known), or conditions, and drops sold or pending items.

## `includeSold` (type: `boolean`):

Keep listings marked sold or pending.

## `excludeKeywords` (type: `array`):

Drop listings whose title or description contains any of these words, for example "broken", "parts only", or "wanted".

## `requireKeywordsInTitle` (type: `boolean`):

Only keep listings whose title contains every word of the search keyword.

## `monitoringMode` (type: `boolean`):

Remember listing IDs in a named key-value store, and output only listings that weren't returned by earlier runs of the same search. Schedule the Actor (for example, hourly) and connect a webhook, Slack, or email integration to get alerts.

## `monitoringStoreName` (type: `string`):

Name of the key-value store that keeps seen IDs. It is created automatically and persists between runs.

## `monitoringKey` (type: `string`):

Optional label for this watch, for example "dallas-bikes". Leave empty to derive one automatically from the search settings.

## `emitPriceChanges` (type: `boolean`):

In monitoring mode, output a previously seen listing again when its price changes. That output has monitoringStatus PRICE_CHANGED and includes previousPrice.

## `monitoringRetentionDays` (type: `integer`):

Forget seen IDs that haven't appeared for this many days.

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

We recommend residential proxies because Facebook blocks most datacenter IPs.

## `maxRetries` (type: `integer`):

Retries per page. Each retry uses a new proxy IP and fresh cookies.

## `cookies` (type: `array`):

Not required, because the Actor works logged out. Only provide cookies if you understand the risk to your account. Use the format \[{"name":"c_user","value":"..."}].

## `debugSaveResponses` (type: `boolean`):

Save raw pages to the run's key-value store for troubleshooting.

## Actor input object example

```json
{
  "searchQueries": [
    "bike"
  ],
  "location": "Dallas, TX",
  "radiusUnit": "miles",
  "daysSinceListed": "any",
  "deliveryMethod": "all",
  "sortBy": "best_match",
  "maxItems": 50,
  "maxPagesPerSearch": 10,
  "includeDetails": true,
  "detailsConcurrency": 4,
  "strictFiltering": true,
  "includeSold": false,
  "requireKeywordsInTitle": false,
  "monitoringMode": false,
  "monitoringStoreName": "fb-marketplace-monitor",
  "emitPriceChanges": true,
  "monitoringRetentionDays": 60,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  },
  "maxRetries": 5,
  "debugSaveResponses": false
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset of Marketplace listings

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

Overview table view

## `runStats` (type: `string`):

Requests, retries, pages, filtered and skipped counts

# 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 = {
    "searchQueries": [
        "bike"
    ],
    "location": "Dallas, TX",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("kingly_contest_7cb/facebook-marketplace-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 = {
    "searchQueries": ["bike"],
    "location": "Dallas, TX",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("kingly_contest_7cb/facebook-marketplace-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 '{
  "searchQueries": [
    "bike"
  ],
  "location": "Dallas, TX",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call kingly_contest_7cb/facebook-marketplace-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kingly_contest_7cb/facebook-marketplace-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/h4gd7igm19QrXWWCx/builds/691Ypz0jZkkW61oT6/openapi.json
