# Facebook Marketplace Scraper - Keyword Search (`scrapesage/facebook-marketplace-scraper`) Actor

Search Facebook Marketplace by keyword and city without login: price, condition, city and state, market area, listing age, sold and pending status, delivery types, strikethrough price and photo. Filter by price, condition and age, with monitor mode for new listings.

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

## Pricing

$6.00 / 1,000 listing scrapeds

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/platform/actors/running/actors-in-store#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

## Facebook Marketplace Scraper - Keyword Search

Search **Facebook Marketplace by keyword and city without a login** and get a listing record that actually has the fields you need: **price, condition, city and state, listing age, sold/pending status, delivery types, strikethrough price** and the photo.

### Why this one

The popular Marketplace scraper advertises 9 output fields. Look closely and it is **four fields duplicated** in snake\_case and camelCase:

```
primary_listing_photo  +  primaryListingPhoto
marketplace_listing_title  +  listingTitle
listingUrl  +  itemUrl
listing_price.formatted_amount  +  listingPrice.formatted_amount
```

No condition. No location. No listing age. No sold status. And its input **requires `startUrls`** - there is no keyword search at all.

| | This actor | Typical incumbent |
|---|---|---|
| **Keyword + city search** | ✅ | ❌ start URLs only |
| Category browse | ✅ | partial |
| Price (numeric **and** formatted) | ✅ | formatted only |
| **Condition** (new / used / used like new) | ✅ on category lane | ❌ |
| **City + state + market area** | ✅ | ❌ |
| **Listing age in days** | ✅ | ❌ |
| Sold / pending status | ✅ | ❌ |
| Strikethrough (reduced) price | ✅ | ❌ |
| Delivery types | ✅ | ❌ |
| Price / condition / age filters | ✅ | ❌ |
| Monitor mode for new listings | ✅ | ❌ |

### What you get per listing

`listingUrl` · `listingId` · `title` · `customTitle` · **`priceAmount`** · `priceFormatted` · `priceMinorUnits` · `strikethroughPrice` · `minPrice` · `maxPrice` · **`condition`** · `conditionRaw` · **`city`** · **`state`** · `marketArea` · `marketAreaId` · `photoUrl` · `hasVideo` · `categoryId` · `listedAt` · `listedTimestamp` · **`listingAgeDays`** · `isSold` · `isPending` · `isLive` · `deliveryTypes[]` · `listingTags[]` · `sellerAvailable` · `query` · `queryType` · `searchCity` · `scrapedAt`

### Input

```json
{
  "searchQueries": ["bicycle", "iphone"],
  "cities": ["nyc", "la"],
  "minPrice": 50,
  "maxPrice": 500,
  "maxListingAgeDays": 14,
  "excludeSold": true,
  "maxResults": 100,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

| Field | What it does |
|---|---|
| `searchQueries` | Keywords - searched in every city you list |
| `cities` | Marketplace locality slugs: `nyc`, `la`, `chicago`, `houston`, `seattle`… |
| `categories` | Browse a category instead (`bikes`, `furniture`, `electronics`) - **this lane also returns `condition`** |
| `startUrls` | Any marketplace search/category URL, used as-is |
| `condition` | Keep only matching conditions (`new`, `used`, `used like new`) |
| `minPrice` / `maxPrice` | Price window |
| `maxListingAgeDays` | Freshness window |
| `excludeSold` | Drop sold/pending (on by default) |
| `onlyNewListings` | Monitor mode - a clean deal-alert feed |

### Honest limits - read before you buy

- **`condition` comes from the category lane, not the search lane.** Measured on 2026-07-30: `condition` is populated on **14/14** listings from a category browse and **0/14** from a keyword search - Facebook simply omits the field from its search payload. If condition matters to you, pass `categories` (e.g. `["bikes"]`) instead of, or as well as, `searchQueries`. Everything else (price, city, state, listing age, status, photo) is present on **both** lanes.
- **No seller identity, by design and by availability.** `marketplace_listing_seller` exists in the payload but is **null** for logged-out callers, and item detail pages are login-walled. Rather than hide that, every row carries `sellerAvailable: false`. This is also the safest outcome for personal data - the actor returns marketplace inventory, not people.
- **No description field.** The full item description lives on the login-walled detail page. The actor returns the listing title (and `customTitle` where Facebook sets one) rather than pretending to have a description.
- **~14-24 listings per search page.** Volume comes from breadth - more keywords and more cities - not deep pagination. A 6-keyword x 4-city run returned **222 listings**.
- **Some searches return a shell.** Facebook occasionally serves a logged-out shell; the actor retries on fresh IPs up to 4 times, then ends successfully with a clear status and **$0 billed** for that query.

### Pricing (pay per event, no start fee)

| Event | Price | What it covers |
|---|---|---|
| `listing` | **$0.006** | One listing with price, condition (category lane), city/state, market area, listing age, status, delivery types and photo |

Listings are billed **before** they are written, and listings removed by your filters are never billed.

### Use with AI assistants (MCP)

Works as an LLM tool via the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) - ask an assistant for "used bikes under $300 in Chicago listed this week" and it can call this actor directly.

### Agent-ready: autonomous payments (x402 & Skyfire)

This actor is **agent-ready** — AI agents can discover it, run it, and **pay for it autonomously**, with no Apify account and no human in the loop. It uses [pay-per-event](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event) pricing and [limited permissions](https://docs.apify.com/platform/actors/development/permissions), so it qualifies for Apify's agentic-payment standards:

- **[x402](https://docs.apify.com/platform/integrations/x402)** — an open, HTTP-native payment protocol. Agents pay per run in USDC on the Base network directly through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) — no account, no API key.
- **[Skyfire](https://docs.apify.com/platform/integrations/skyfire)** — agent-to-service payments for fully autonomous AI-agent workflows.

Building an AI agent, MCP tool, or autonomous data pipeline? This scraper is ready to plug in and pay as it goes.

### Integrations

[Make](https://apify.com/integrations/make), [Zapier](https://apify.com/integrations/zapier), [Slack](https://apify.com/integrations/slack), [Google Drive](https://apify.com/integrations/google-drive), [Airbyte](https://apify.com/integrations/airbyte), [GitHub](https://apify.com/integrations/github), the [Apify API](https://docs.apify.com/api/v2), [Schedules](https://docs.apify.com/platform/schedules) and [Webhooks](https://docs.apify.com/platform/integrations/webhooks).

### Monitor mode

`onlyNewListings: true` remembers what it has already returned for that query set and emits only new listings - pair it with [Apify Schedules](https://docs.apify.com/platform/schedules) for a deal-alert feed that never repeats itself.

### FAQ

**Do I need a login or cookies?** No.

**Why is condition empty?** You searched by keyword. Facebook only ships `condition` on the category lane - see the limits section, with the measured numbers.

**Can I get the seller's name?** No - it is null for logged-out callers and the detail page requires a login. Every row says so via `sellerAvailable`.

**How do I find city slugs?** They are the segment in a Marketplace URL: `facebook.com/marketplace/nyc/...` → `nyc`.

### Related scrapers by scrapesage

- [Facebook Reels Scraper](https://apify.com/scrapesage/facebook-reels-scraper) - exact play counts and reaction breakdown
- [Facebook Ad Library Scraper](https://apify.com/scrapesage/facebook-ad-library-scraper) - Meta ad creatives and advertiser intel
- [eBay Scraper](https://apify.com/scrapesage/ebay-scraper) - resale pricing comparison
- [Craigslist Scraper](https://apify.com/scrapesage/craigslist-scraper) - the other big local-classifieds source

# Actor input Schema

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

What to search for, e.g. bicycle, iphone 15, dining table. This is the input the popular Marketplace scrapers do not offer at all.

## `cities` (type: `array`):

Facebook Marketplace locality slugs, e.g. nyc, la, chicago, houston, seattle. Each keyword is searched in each city. Defaults to nyc.

## `categories` (type: `array`):

Browse a category instead of searching, e.g. bikes, furniture, electronics, propertyrentals.

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

Any facebook.com/marketplace search or category URL, used as-is.

## `condition` (type: `array`):

Keep only listings whose condition matches, e.g. new, used, used like new. Matched loosely against the source value.

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

Skip listings below this price. Listings with no numeric price are skipped when this is set.

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

Skip listings above this price.

## `maxListingAgeDays` (type: `integer`):

Only listings posted within this many days. 0 disables the filter.

## `excludeSold` (type: `boolean`):

Drop listings already marked sold or pending. On by default.

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

Total listings across all searches. 0 means no limit (the run's time budget stops it safely).

## `onlyNewListings` (type: `boolean`):

Remembers listings already returned for this query set and emits only unseen ones - a clean deal-alert feed on a schedule.

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

RESIDENTIAL is the tested default and strongly recommended - Facebook rate-limits datacenter ranges hard.

## Actor input object example

```json
{
  "searchQueries": [
    "bicycle"
  ],
  "cities": [
    "nyc"
  ],
  "maxListingAgeDays": 0,
  "excludeSold": true,
  "maxResults": 100,
  "onlyNewListings": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

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

Every matching listing with price, condition, city and state, market area, listing age, sold/pending status, delivery types and photo as JSON items in the default dataset.

# 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"
    ],
    "cities": [
        "nyc"
    ],
    "excludeSold": true,
    "maxResults": 100,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/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"],
    "cities": ["nyc"],
    "excludeSold": True,
    "maxResults": 100,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapesage/facebook-marketplace-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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"
  ],
  "cities": [
    "nyc"
  ],
  "excludeSold": true,
  "maxResults": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call scrapesage/facebook-marketplace-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=scrapesage/facebook-marketplace-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/3kVoehbTNsbSnlGjI/builds/qcqStGtzyc8x6JJc3/openapi.json
