Field guide · 2026

Scraping Facebook Marketplace: what you actually get, and what stops you

There is no public API. There is a login wall, a location lock, and a hard cap per search. Here is how to work around all three and pull listings as clean JSON.

Open the Marketplace Actor →

Facebook Marketplace is the largest classifieds surface on the planet, and for resellers, price researchers and local-market analysts it is irreplaceable. It is also one of the more awkward targets to pull data from, because Meta never built it to be read by machines. This guide is the practical version: the constraints that actually bite, the fields you can count on, and the shape of a working extraction pipeline.

The first thing to understand: there is no API

Meta offers a Commerce / Catalog API, but that is for you to upload your own inventory as a seller. There is no public endpoint to browse, search, or read other people's listings. Anyone selling you a "Marketplace API" is, under the hood, scraping the public web view that loads at facebook.com/marketplace. That is not a workaround you bolt on later — it is the only path that exists, so plan around it from the start.

The three walls you will hit

1. The location lock

Marketplace is fundamentally local. Every query is scoped to a city or a latitude/longitude pair plus a search radius (Facebook's UI tops out around 500 miles, but practical results thin out far sooner). You cannot ask for "all listings in the US" in one call. If you want national coverage you seed a list of cities, run the same keyword against each, and merge.

2. The result cap

A single search location returns a few hundred items at most before the infinite scroll dries up — Facebook does not paginate you through tens of thousands of results. The lever that actually expands your dataset is more location + keyword combinations, not a bigger maxItems on one query.

3. The login wall on detail pages

Search and category grids render publicly in most regions, so titles, prices, thumbnails and the listing's city come through without a session. But the full description, posting date, and seller profile frequently sit behind a logged-in view. A maintained scraper deals with this using managed sessions and residential proxies; rolling your own means babysitting accounts that get checkpointed constantly.

Honest expectation: treat the grid-level fields (title, price, location, image, listing URL) as reliable at volume, and the detail-level fields (full description, exact post time, seller name) as best-effort. Build your analysis on the reliable set.

The fields a Marketplace scrape returns

A clean run gives you one row per listing. Here is what each row typically carries and how trustworthy it is:

FieldExampleReliability
id1294857361029384High — your dedup key
title"IKEA Malm dresser, 6 drawer, white"High
price120 (numeric) + currencyHigh — watch for "Free" and "Please contact"
location"Austin, TX"High (city-level, not address)
image / images[]CDN thumbnail URLsHigh for first image
listingUrl/marketplace/item/12948.../High
descriptionFree-text bodyMedium — may need login view
postedAt"3 days ago" / timestampMedium — often relative, not absolute
sellerName"Jordan M."Low / variable

A worked example: used-goods price research

Say you flip mid-century furniture and you want to know what a teak sideboard actually clears for across three metros. The naive approach — eyeballing listings — conflates asking price with sold price and ignores how long things sit. A structured pull fixes that:

  1. Seed locations. Pick Austin, Dallas and Houston as coordinate+radius pairs.
  2. Run the keyword "teak sideboard" against each, ~150 items per metro.
  3. De-duplicate by id (cross-posted listings appear in overlapping radii).
  4. Normalize price: drop "Free" and contact-for-price rows, parse the rest to a number.
  5. Bucket and chart the price distribution. The median and the interquartile range tell you the real market, not the one optimistic $900 outlier.

Re-run it weekly and you also get turnover: listings that vanish between runs are your proxy for what sells, and at what price band.

Wiring it into a pipeline

You do not have to touch any of the proxy/session machinery. With a maintained actor you POST a job and read back a dataset. A realistic call against multiple location seeds looks like this:

curl -X POST "https://api.apify.com/v2/acts/renzomacar~facebook-marketplace-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "keyword": "teak sideboard",
    "locations": ["Austin, TX", "Dallas, TX", "Houston, TX"],
    "radiusMiles": 60,
    "maxItemsPerLocation": 150,
    "extendDetails": true
  }'

The response is an array of listing objects. Append &format=csv to the dataset URL and the same data comes back as a spreadsheet instead — handy when the consumer is a non-technical teammate or a Google Sheet.

Two gotchas worth pre-empting

Skip the proxy and session headache

Our maintained Facebook Marketplace Actor handles the login wall, the location seeding and the proxies, and hands you listings as clean JSON or CSV. Free Apify credits to start.

Get the Marketplace Scraper → Or get done-for-you leads

Disclosure: the links to Apify on this page are affiliate links. If you create a paid account through them we may earn a commission, at no extra cost to you. We recommend Apify because we build and ship the Facebook Marketplace Actor on it ourselves.