# Facebook Marketplace Scraper (`mina_safwat/facebook-marketplace-scraper`) Actor

Scrape Facebook Marketplace search and category results — title, price, location, photo and listing date — with every filter from your link, newest-first monitoring and optional full listing details.

- **URL**: https://apify.com/mina_safwat/facebook-marketplace-scraper.md
- **Developed by:** [Mina](https://apify.com/mina_safwat) (community)
- **Categories:** E-commerce, Social media, Lead generation
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 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

### What does Facebook Marketplace Scraper do?

**Facebook Marketplace Scraper** turns any [Facebook Marketplace](https://www.facebook.com/marketplace/)
search or category link into a clean table of listings: **title, price, city,
photo, listing date, sold/pending status and delivery options**. Paste the link
exactly as it appears in your browser and **every filter in it is kept**: price
range, condition, date listed, sort order, radius, and the vehicle year and
mileage filters.

It also works as a **Marketplace monitor**: switch on *Only new listings since
the last run*, schedule it, and each run returns just the listings that
appeared since the previous one. Turn on *Include listing details* to add the
**full description, condition, every photo, approximate map position, distance
from your search location and vehicle specifications**.

No Facebook account, cookies or browser extension are needed. Because it runs
on the Apify platform you also get API access, scheduling, integrations
(Google Sheets, Make, Zapier, n8n, webhooks), run monitoring and automatic
proxy rotation.

### Why scrape Facebook Marketplace?

- **Deal hunting and reselling**: catch underpriced items, cars and furniture
  minutes after they are listed.
- **Price research**: see what used goods really sell for in a city, by
  condition and category.
- **Car market analysis**: collect make, model, mileage, transmission and
  asking price for every vehicle in a region.
- **Lead and inventory monitoring**: alert your team, a Slack channel or a CRM
  whenever a matching listing appears.
- **Market research**: compare supply and pricing across cities.

### How to scrape Facebook Marketplace

1. Open [facebook.com/marketplace](https://www.facebook.com/marketplace/), pick
   a city and search for something, or open a category such as **Vehicles** or
   **Electronics**.
2. Set Facebook's own filters: price, condition, date listed, sort order and so on.
3. Copy the address from your browser's address bar.
4. Paste it into **Marketplace links**. Add more links, one per line.
5. Click **Start**. The prefilled example returns 24 fresh bike listings in New
   York in under 30 seconds.
6. Download the results as JSON, CSV, Excel or HTML, or send them to another app.

#### Monitoring new listings

1. Use a link sorted by **Date listed: Newest first** (`sortBy=creation_time_descend`).
   For searches, also pick **Date listed: Last 24 hours** (`daysSinceListed=1`).
   Without a date filter, Facebook's logged-out search starts about a day back.
2. Switch on **Only new listings since the last run**.
3. Create a **schedule**, for example every 15 minutes, and connect a webhook,
   Slack, email or Google Sheets integration.

Each run reads the top *Max listings per link* listings and outputs only the
ones it has not delivered before for that exact link. Facebook shows each
logged-out visitor a slightly different selection of recent listings, so a run
can also surface a listing posted a little earlier that previous runs did not
see; it is still new to you. The list of delivered listings is kept in a named
key-value store, `facebook-marketplace-monitor`, in your own Apify account.
Delete it to start over.

### Input

Everything is set on the Input tab. In JSON, the input looks like this:

```json
{
    "startUrls": [
        { "url": "https://www.facebook.com/marketplace/nyc/search?query=bike&sortBy=creation_time_descend&daysSinceListed=1" },
        { "url": "https://www.facebook.com/marketplace/la/vehicles?minYear=2015&maxMileage=80000&sortBy=creation_time_descend" }
    ],
    "maxListingsPerUrl": 100,
    "onlyNewSinceLastRun": false,
    "includeDetails": false
}
```

| Field | What it does |
|---|---|
| `startUrls` | Marketplace search or category links, for any city or numeric location id. The link must include the location (…/marketplace/nyc/…). All filters in the link are used. |
| `maxListingsPerUrl` | Stops each link after this many listings. Default 100; Facebook serves 24 per page. |
| `onlyNewSinceLastRun` | Outputs only listings not delivered for the same link in an earlier run. |
| `includeDetails` | Opens each listing's page for the description, photos, position, distance, currency and vehicle data. |
| `proxyConfiguration` | Keep the default residential proxy. Facebook sends data-centre connections to its login page. |

**Radius.** A `radius=` value in the link is applied to category feeds such as
Vehicles. Facebook's search results are ranked by distance but not cut off at
the radius for logged-out visitors, so with **Include listing details** on, the
Actor measures each listing's distance and drops the ones outside your radius.
Facebook places many listings at their city's centre point, so a radius smaller
than the city still keeps listings from the whole city.

**Year and mileage.** Facebook ignores vehicle year and mileage filters for
logged-out visitors, so the Actor applies `minYear`, `maxYear`, `minMileage` and
`maxMileage` from your link itself, using the year at the start of the title and
the mileage shown on the listing. Listings outside them are skipped and never
billed, but they count toward `maxListingsPerUrl`. A listing that shows no year
or mileage is kept.

### Output

Each listing is one row. A real example with details on, shortened:

```json
{
    "listingId": "1674610777389402",
    "url": "https://www.facebook.com/marketplace/item/1674610777389402/",
    "title": "Car Bike Rack - 4 Bikes",
    "price": 100.0,
    "formattedPrice": "$100",
    "listedAt": "2026-10-01T18:01:12+00:00",
    "city": "New York",
    "state": "NY",
    "locationName": "New York, New York",
    "photoUrl": "https://scontent.xx.fbcdn.net/v/t39.84726-6/8304...jpg",
    "isSold": false,
    "isPending": false,
    "deliveryTypes": ["IN_PERSON", "PUBLIC_MEETUP", "DOOR_PICKUP"],
    "categoryId": "1383948661922113",
    "description": "Car Bike Rack for 4 bicycles\n\nIn good condition...",
    "condition": "Used – good",
    "categoryName": "Sport and outdoors",
    "currency": "USD",
    "photos": ["https://scontent.xx.fbcdn.net/v/t39.84726-6/8304...jpg", "..."],
    "locationText": "New York, NY",
    "latitude": 40.8554,
    "longitude": -73.9325,
    "distanceKm": 16.9,
    "shippingOffered": false
}
```

A vehicle listing with details adds a `vehicle` object:

```json
{
    "title": "2020 Hyundai Ioniq Plug-in Hybrid · SE Hatchback 4D",
    "subtitles": ["107K miles"],
    "vehicle": {
        "make": "Hyundai", "model": "Ioniq Plug-in Hybrid", "trim": "SE Hatchback 4D",
        "transmission": "AUTOMATIC", "fuelType": "PLUGIN_HYBRID",
        "exteriorColor": "blue", "interiorColor": "grey",
        "sellerType": "PRIVATE_SELLER", "mileage": 107000, "mileageUnit": "MILES"
    }
}
```

You can download the dataset in various formats such as JSON, HTML, CSV, or
Excel. The Output tab has two views: **Listings** and **Listing details**.

#### Data fields

| Field | Description |
|---|---|
| `listingId`, `url` | Marketplace listing id and link |
| `title` | Listing title |
| `price`, `formattedPrice` | Asking price as a number, and as Facebook shows it |
| `strikethroughPrice` | Earlier price, when the seller cut it |
| `listedAt` | When the listing was posted (UTC) |
| `city`, `state`, `locationName` | Where the item is |
| `photoUrl` | Main photo |
| `subtitles` | Extra card lines, such as a car's mileage |
| `isSold`, `isPending`, `hasVideo` | Listing status flags |
| `deliveryTypes` | Pickup, meetup or shipping options |
| `categoryId` | Marketplace category id |
| `description`, `condition`, `attributes` | Details only: full text, condition and seller-set attributes |
| `categoryName`, `currency` | Details only |
| `photos` | Details only: every photo |
| `locationText`, `latitude`, `longitude` | Details only: approximate position, as Facebook shows it on the map |
| `distanceKm` | Details only: distance from the searched location |
| `shippingOffered` | Details only |
| `vehicle` | Details only, vehicles: make, model, trim, mileage, transmission, fuel, colours, title status, seller type |
| `sellerName`, `sellerId` | Only when Facebook shows the seller to logged-out visitors, which is rare |

### How much does it cost to scrape Facebook Marketplace?

The Actor is priced **per listing** (pay per event), so you only pay for rows in
your dataset. Listings collected with **Include listing details** carry one extra
event for the listing page, because every listing page is a separate, much
heavier download. Links that return nothing are never billed: they are listed
in the `FAILED_INPUTS` record instead. See the **Pricing** tab for the current
prices. Apify's free plan credits cover a few thousand listings a month.

### Tips

- **Keep details off** unless you need descriptions, photos or exact distances;
  a run without details is several times faster and cheaper.
- **Use newest-first links for monitoring**, plus *Last 24 hours* for searches,
  and keep *Max listings per link* small (24–48). Frequent runs, every 10–30
  minutes, catch more listings than one large run a day.
- **Set a maximum cost** for the run on the run options. The Actor stops
  cleanly when it is reached.
- One run can mix any number of cities and categories.

### FAQ, disclaimers, and support

**Is it legal to scrape Facebook Marketplace?** This Actor reads only what
Facebook shows to any visitor who is not logged in. It does not log in, and
it does not collect private messages or anything behind a login. Your use of
the data must still respect Facebook's terms and the laws that apply to you.

**Personal data.** Listing descriptions and, occasionally, seller names are
**personal data** under the GDPR and similar laws. Only collect them with a
legitimate reason, keep them secure, and do not use them for spam or
profiling. Ask a lawyer if you are unsure.

**Which links work?** Search links (`/marketplace/<city>/search?query=...`)
and category links (`/marketplace/<city>/vehicles`, `/marketplace/<city>/electronics`).
The link must name a city or location id: links without one, such as
`/marketplace/category/<name>`, are reported in `FAILED_INPUTS`. Property rentals
are shown only to logged-in Facebook users, so those links are reported there
too. The Marketplace home page and single listing links are not searches and are
skipped.

**Why did a link return nothing?** The run's status message and the
`FAILED_INPUTS` record in the key-value store give the reason for every link,
for example a misspelled city name or a search with no matches. When Facebook
finds no exact match it suggests similar items; the Actor does not count
those as results.

**Seller details?** Facebook hides sellers from logged-out visitors on almost
every listing, so seller fields are usually empty.

Found a bug or need another field? Open an issue on the **Issues** tab. A custom
version of this Actor is available on request.

# Actor input Schema

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

Facebook Marketplace search or category links, one per line. Open Marketplace, pick a city, search or open a category (Vehicles, Electronics, ...), set any filters you like — price, condition, date listed, sort order, radius, year, mileage — and copy the address bar. Every filter in the link is used. To watch for new listings, sort by "Date listed: Newest first" (sortBy=creation_time_descend) and, for searches, also pick "Last 24 hours" (daysSinceListed=1): without a date filter Facebook's logged-out search starts about a day back.

## `maxListingsPerUrl` (type: `integer`):

Stops reading each link after this many listings. Facebook serves 24 per page.

## `onlyNewSinceLastRun` (type: `boolean`):

For monitoring. The Actor remembers which listings it already delivered for each link and outputs only the ones it has not delivered before, so a scheduled run returns just the new arrivals. It still reads up to "Max listings per link" from the top of the feed, so use a newest-first link. The memory lives in a named key-value store, facebook-marketplace-monitor, in your account.

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

Also opens every listing's own page to add the description, condition, all photos, approximate map position, distance from the searched location, currency, shipping and vehicle specifications (make, model, mileage, transmission...). Each listing page is a separate, heavier request, so detailed listings are billed with an extra event and runs are slower.

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

Keep the residential proxy. Facebook sends data-centre connections, Apify's own included, to its login page, so without it every link is refused. Each new visit draws a fresh residential address.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.facebook.com/marketplace/nyc/search?query=bike&sortBy=creation_time_descend&daysSinceListed=1"
    }
  ],
  "maxListingsPerUrl": 24,
  "onlyNewSinceLastRun": false,
  "includeDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `dataset` (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.facebook.com/marketplace/nyc/search?query=bike&sortBy=creation_time_descend&daysSinceListed=1"
        }
    ],
    "maxListingsPerUrl": 24,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("mina_safwat/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 = {
    "startUrls": [{ "url": "https://www.facebook.com/marketplace/nyc/search?query=bike&sortBy=creation_time_descend&daysSinceListed=1" }],
    "maxListingsPerUrl": 24,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("mina_safwat/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 '{
  "startUrls": [
    {
      "url": "https://www.facebook.com/marketplace/nyc/search?query=bike&sortBy=creation_time_descend&daysSinceListed=1"
    }
  ],
  "maxListingsPerUrl": 24,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call mina_safwat/facebook-marketplace-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mina_safwat/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/nC8r40aN1MIrdfAXj/builds/lzwYR5oLxXGw7R0VV/openapi.json
