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

Search Facebook Marketplace by keyword, city, category, price, condition and date listed. Get title, price, currency, location, photo, seller and posting time for every listing, plus description, condition and vehicle details on request. No Facebook account needed.

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

## Pricing

from $3.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

## Facebook Marketplace Scraper - Listings, Prices & Sellers

Search Facebook Marketplace the way you would in your browser: type what you are looking for, pick a city, and narrow it down by category, price range, condition, how recently it was listed and how far away. Every listing becomes one row with its title, price and currency, city and state, main photo, seller name, the time it was posted, sold or pending status and delivery options. Searches return hundreds of listings each, not just the first screen.

Turn on full listing details to add the description, condition, all photos, the map position, the seller's rating, the category name and, for cars and other vehicles, make, model, trim, mileage, transmission, colours and title status. You can also paste Marketplace search links straight from your browser. No Facebook account is needed.

### Quick Start

```json
{
  "searchQueries": [
    "bicycle"
  ],
  "location": "nyc",
  "maxItemsPerSearch": 100,
  "includeDetails": false
}
```

More examples:

- Cheapest desks over $20 in Chicago with full details: `{"searchQueries": ["desk"], "location": "chicago", "minPrice": 20, "sortBy": "priceLowToHigh", "includeDetails": true, "maxItemsPerSearch": 50}`
- Newest cars under $9,000 in Austin: `{"category": "vehicles", "location": "austin", "maxPrice": 9000, "sortBy": "newest", "maxItemsPerSearch": 300}`
- Several products in one city, listed this week: `{"searchQueries": ["iphone 13", "ipad", "macbook"], "location": "la", "daysSinceListed": "7"}`
- Free stuff near you: `{"category": "free", "location": "seattle", "sortBy": "distance"}`
- A search you set up on Marketplace: `{"startUrls": [{"url": "https://www.facebook.com/marketplace/houston/search/?query=couch&maxPrice=300"}]}`

### Input

| Input | Type | Default | Meaning |
| --- | --- | --- | --- |
| `searchQueries` | array | — | What to search for, as you would type it on Marketplace. Each term is one search. |
| `location` | string | `nyc` | The city as it appears after `/marketplace/` in a Marketplace link (`nyc`, `la`, `chicago`, `austin`, `london`, `toronto`), or the numeric location id from such a link. |
| `category` | string | — | One of `vehicles`, `electronics`, `furniture`, `household`, `apparel`, `family`, `toys`, `hobbies`, `sports`, `instruments`, `entertainment`, `garden`, `pets`, `classifieds`, `free`. With search terms it narrows them; on its own it lists the category. |
| `startUrls` | array | — | Links copied from a Marketplace search or category page. The link's own filters are kept. |
| `maxItemsPerSearch` | integer | `100` | Cap on rows for each search term or link (up to 5,000). |
| `maxItems` | integer | `1000` | Cap on rows for the whole run (up to 50,000). |
| `includeDetails` | boolean | `false` | Open each listing to add the description, condition, all photos, map position, seller rating, category name and vehicle details. Slower, and charged as a detail add-on. |
| `minPrice`, `maxPrice` | integer | — | Price range in the local currency of the location. |
| `sortBy` | string | `relevance` | `relevance`, `newest`, `priceLowToHigh`, `priceHighToLow` or `distance`. |
| `daysSinceListed` | string | — | `1`, `7` or `30`: only listings posted in that many days. |
| `itemCondition` | array | all | Any of `new`, `used_like_new`, `used_good`, `used_fair`. |
| `radiusKm` | integer | about 65 | Distance around the location to search, in kilometres. |

Give at least one search term, a category or a Marketplace link. The filters apply to every search term and to the category; links keep their own. A listing that appears in more than one search is returned once.

### What it returns

The dataset contains one row per listing:

| Field | Meaning |
| --- | --- |
| `listingId`, `url` | Marketplace listing id and the listing page. |
| `title` | Listing title. |
| `price`, `priceText`, `currency` | Asking price as a number (0 for free items), as shown (`$1,200`, `CA$20`, `£10`) and as an ISO code. |
| `originalPriceText` | The earlier price Marketplace shows struck through after a price drop. |
| `city`, `state`, `locationText` | Where the item is. |
| `imageUrl`, `photos` | Main photo, and every photo with full details. |
| `subtitles` | Extra lines on the result card, such as a car's mileage. |
| `sellerName` | The seller's name exactly as shown on the listing page. |
| `postedAt` | When the listing was posted (UTC, ISO 8601). |
| `isSold`, `isPending` | Sold and pending status. |
| `deliveryTypes`, `shippingOffered` | Pickup and delivery options (`IN_PERSON`, `DOOR_PICKUP`, `SHIPPING_OFFSITE`, …) and whether shipping is offered. |
| `categoryId`, `categoryName` | Marketplace category id, and its name with full details (for example `Furniture`). |
| `condition`, `attributes` | Condition (for example `Used - like new`) and the other listing attributes, with full details. |
| `description` | The seller's description (with full details). |
| `vehicle` | For vehicle listings with full details: `make`, `model`, `trim`, `mileage`, `mileageUnit`, `transmission`, `exteriorColor`, `interiorColor`, `fuelType`, `titleStatus`, `sellerType`. Otherwise `null`. |
| `detailLevel` | `listing` for search-result fields only, `full` when the listing's details were added. |
| `searchInput`, `searchUrl` | The search term, category or link you supplied, and the Marketplace search the row came from. |
| `scrapedAt` | Collection time (UTC, ISO 8601). |
| `error` | Always `null` in the dataset. Failures are reported in the run summary instead. |

Fields the listing does not show are `null` (or an empty list), never guessed.

The run summary (`OUTPUT`) reports `results`, `detailedResults`, one entry per started search in `searches` (pages read, listings encountered and rows delivered), `errors` with the list at `searchErrors`, and `detailErrors` for listings whose details could not be opened.

After five consecutive searches return zero listings, the run stops and logs a warning naming the remaining searches skipped. `emptySearches` counts successful searches with zero listings; `searchesSkipped` and `skippedSearches` report how many searches were not started and their inputs and URLs. `stoppedBy: "emptySearchLimit"` identifies this stop. Searches that fail or return listings (even duplicates) break the empty-search streak. A search also ends after three result pages in a row add no new listings, including pages containing only duplicates. These stops do not add any charge event.

### Example queries

- **Price research:** search one product across several cities and compare `price` and `postedAt`.
- **Deal alerts:** schedule a run sorted by `newest` with a `maxPrice` and get the fresh listings every hour.
- **Used-car lists:** collect the `vehicles` category with full details for make, model, mileage and title status.
- **Reseller sourcing:** search `free` or a low price range in your city and sort by `distance`.
- **Market snapshots:** export a category to a spreadsheet to see what sells in a city and at what price.

### Output example

```json
{
  "listingId": "2501167960380368",
  "url": "https://www.facebook.com/marketplace/item/2501167960380368/",
  "title": "Small Wooden Desk",
  "price": 20,
  "priceText": "$20",
  "currency": "USD",
  "originalPriceText": null,
  "city": "Lake in the Hills",
  "state": "IL",
  "locationText": "Lake in the Hills, IL",
  "imageUrl": "https://scontent-ord5-1.xx.fbcdn.net/v/t39.84726-6/707981212_n.jpg",
  "photos": [
    "https://scontent-ord5-1.xx.fbcdn.net/v/t39.84726-6/707981212_n.jpg",
    "https://scontent-ord5-1.xx.fbcdn.net/v/t39.84726-6/707981213_n.jpg"
  ],
  "subtitles": [],
  "sellerName": "Samantha L.",
  "postedAt": "2026-05-26T23:37:10Z",
  "isSold": false,
  "isPending": false,
  "deliveryTypes": [
    "IN_PERSON",
    "DOOR_PICKUP"
  ],
  "shippingOffered": false,
  "categoryId": "1583634935226685",
  "categoryName": "Furniture",
  "condition": "Used - Good",
  "description": "Small wooden desk with shelves, used in a college apartment. Good condition. Pickup only.",
  "attributes": [
    {
      "name": "Condition",
      "value": "Used - Good"
    },
    {
      "name": "Material",
      "value": "Wood"
    }
  ],
  "vehicle": null,
  "detailLevel": "full",
  "searchInput": "desk",
  "searchUrl": "https://www.facebook.com/marketplace/chicago/search/?query=desk&minPrice=20&sortBy=price_ascend",
  "scrapedAt": "2026-10-20T05:02:11Z",
  "error": null
}
```

### Failed searches and listings

A location Marketplace does not recognise, or a search that could not be read, is reported in the run summary at `OUTPUT.searchErrors` with its input, `code` and `message`. When a listing's full details cannot be opened, the listing is still delivered with `detailLevel` `listing` and is listed in `OUTPUT.detailErrors`. Failures are never dataset rows and are not charged. If no listing at all could be collected, the run ends with an error instead of finishing green with an empty dataset.

### Limits and caveats

- Only what Marketplace shows publicly on a listing is returned. Sellers' contact details are not shown on Marketplace and are not collected.
- The location is a Marketplace city name or location id, not a street address. Use `radiusKm` to widen or narrow the area.
- Marketplace mixes in some listings from nearby areas and, for some searches, items that ship from further away; `city`, `state` and `deliveryTypes` show where each one is.
- Prices are in the listing's own currency. US-dollar prices show as `$`, other dollars as `CA$`, `A$`, `MX$` and so on.
- Full details take about 1.5 to 2 seconds per listing; search results alone come back about 25 at a time.
- Automated access is subject to Facebook's terms; use this actor only where you have the necessary permissions and a lawful basis, and handle personal data (such as seller names) in line with the privacy laws that apply to you.

### FAQ

**Do I need a Facebook account?** No. Only public listing information is collected.

**How do I find my city's location name?** Open Marketplace in your browser, choose the city, and copy the word after `/marketplace/` in the address bar (for example `nyc` in `facebook.com/marketplace/nyc/`). You can also paste that whole search link into `startUrls`.

**How many listings can one search return?** Usually several hundred to over a thousand for a broad search in a big city; set `maxItemsPerSearch` up to 5,000. Narrow searches return fewer.

**How fast is it?** Search results: roughly 1,000 listings in 2 to 3 minutes. With full details: roughly 1,000 listings in 25 to 35 minutes.

### Price

**$0.003 per listing**, **$0.004 per detailed listing** ($0.003 listing + $0.001 detail add-on), plus **$0.005 per run start**. A detailed listing is a row with `includeDetails` on whose details were added; a listing whose details could not be opened is charged as a listing. The run-start event is charged per GB of memory; the default 512 MB run is one start event. The start is charged even if the run saves no results. Failed searches are not charged. When your maximum charge for the run is reached, the run stops and keeps the rows already saved. Platform usage is included in these prices.

# Actor input Schema

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

What to search for, as you would type it on Marketplace (for example bicycle or iphone 13). Each term is one search in the location below.

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

The city as it appears after /marketplace/ in a Marketplace link: nyc, la, chicago, houston, austin, london, toronto. A numeric location id from such a link works too. Defaults to nyc.

## `category` (type: `string`):

Limit the results to one Marketplace category. Without search terms, the newest listings in that category are collected.

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

Links copied from a Marketplace search or category page in your browser, for example https://www.facebook.com/marketplace/austin/vehicles/?maxPrice=9000. The link's own filters are kept.

## `maxItemsPerSearch` (type: `integer`):

Cap on rows for each search term or link (up to 5,000).

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

Cap on rows for the whole run, across every search (up to 50,000).

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

Open each listing to add its description, condition, all photos, exact map position, seller rating, category name and vehicle details. Slower, and charged as a detail add-on per row.

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

Lowest price, in the local currency of the location.

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

Highest price, in the local currency of the location.

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

Order of the results.

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

Only listings posted in the last 1, 7 or 30 days.

## `itemCondition` (type: `array`):

Only listings in these conditions.

## `radiusKm` (type: `integer`):

Distance around the location to search, in kilometres. Marketplace uses about 65 km when left empty.

## Actor input object example

```json
{
  "searchQueries": [
    "bicycle"
  ],
  "location": "nyc",
  "maxItemsPerSearch": 100,
  "maxItems": 1000,
  "includeDetails": false,
  "sortBy": "relevance"
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "searchQueries": [
        "bicycle"
    ],
    "location": "nyc",
    "maxItemsPerSearch": 100,
    "maxItems": 1000,
    "includeDetails": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("barefoot_grade/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": ["bicycle"],
    "location": "nyc",
    "maxItemsPerSearch": 100,
    "maxItems": 1000,
    "includeDetails": False,
}

# Run the Actor and wait for it to finish
run = client.actor("barefoot_grade/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": [
    "bicycle"
  ],
  "location": "nyc",
  "maxItemsPerSearch": 100,
  "maxItems": 1000,
  "includeDetails": false
}' |
apify call barefoot_grade/facebook-marketplace-scraper --silent --output-dataset

```

## MCP server setup

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