Facebook Marketplace Scraper - Listings, Prices, Sold Flag avatar

Facebook Marketplace Scraper - Listings, Prices, Sold Flag

Pricing

from $0.40 / 1,000 listings

Go to Apify Store
Facebook Marketplace Scraper - Listings, Prices, Sold Flag

Facebook Marketplace Scraper - Listings, Prices, Sold Flag

Search Facebook Marketplace by keyword and city. One row per listing: title, price, any price cut, town, link, photo, posted date and sold status. Narrow it by price range and days listed, or change the sort order. About 24 listings a search. No login needed from you. $0.40 per 1,000 listings.

Pricing

from $0.40 / 1,000 listings

Rating

0.0

(0)

Developer

Dami's Studio

Dami's Studio

Maintained by Community

Actor stats

0

Bookmarked

15

Total users

7

Monthly active users

10 hours ago

Last modified

Share

Facebook Marketplace Scraper: listings and prices for a search, in the city you pick

Tell it what you're after and where, and it returns the Facebook Marketplace listings that search turns up, one row each. Every row has the title, the price and any crossed-out price, the seller's town, the listing link, the main photo and how many days the item has been up. The limit to know before you plan a big job: one search returns about 24 listings, Facebook's first page of results, however high you set maxItems.

Two more things. Five filters on the form (condition, category, sold only, exact phrase and radius) don't change the results at the moment, so don't count on them. And the form arrives filled in with a real search, road bikes in Austin, so pressing Start without editing it runs that search and bills what it finds.

InputSearch terms and a place, or Marketplace search links from your browser
OutputOne row per listing
CeilingAbout 24 listings per search, up to 10 searches per run
Account neededNone from you
Price$0.40 per 1,000 listings, flat on every plan

๐Ÿ” What Facebook Marketplace Scraper does

It runs the search you would run on Marketplace yourself, in the place you name, and writes down what Facebook shows. That is Facebook's idea of the area, not a fixed circle. A search for road bikes in Austin also brought back listings from Round Rock, Georgetown and San Antonio.

Up to ten search terms can share a run. The row budget is split evenly between them, and a listing that two of your terms both find comes back once and is charged once.

A place name Facebook doesn't recognise gets quietly answered with listings from some other city. When Facebook's answer says it searched somewhere other than the place you asked for, those listings are thrown away and you get a free WRONG_LOCATION row instead of a bill for the wrong town.

Already built the search in your browser? Paste the link into startUrls and the term, city, price range, day limit and sort order are read out of it. Each link is searched in its own city, so one run can cover several.

๐Ÿ“ฅ What you give it

{
"searchTerms": ["road bike"],
"location": "Austin, TX",
"minPrice": 300,
"maxPrice": 600,
"daysSinceListed": 7,
"maxItems": 24
}
FieldIf you leave it emptyWhat it is
searchTermsyour links only, or the free sample rowWhat to look for, up to 10 terms. The form arrives with road bike in it.
locationthe city in your first link, if anyWhere your search terms are searched: a city name ("Austin, TX", "Manchester"), a Marketplace city slug ("nyc", "la") or a latitude,longitude pair. Marketplace search is local, so a run needs a place. Links keep the city they name.
maxItems20Total listings across all terms, 1 to 1,000, shared evenly between them. Each search still stops at about 24.
minPrice, maxPriceno limitPrice range in the currency of the place you search.
daysSinceListedany ageOnly listings posted in the last 1 to 30 days. Facebook counts whole days, so a row's postedAt can be a little older than that.
sortByFacebook's own orderbest_match, newest, price_low_to_high, price_high_to_low or distance.
startUrlsnoneUp to 10 Marketplace search links, such as https://www.facebook.com/marketplace/nyc/search?query=road%20bike&minPrice=100. Each link is searched in the city it names. One whose city the run can't place (a numeric Facebook location id, for example) falls back to location, with a free NO_LOCATION row. A filter you also set in the fields above wins over the one in the link.
latitude, longitudenoneExact coordinates instead of a place name. Set both or neither.
condition, category, availability, exactMatch, radiusKmno effectOn the form, but the search currently runs as if they were empty.
proxyUrlsemptyOnly if you want the requests to go out through servers of your own, as http://user:pass@host:port.
sessionCookiesemptyYour own Facebook cookies, one account per line, as c_user=โ€ฆ; xs=โ€ฆ. Optional, see the questions below.

๐Ÿ“ค What you get back

A real row from a real run, with the photo link cut short:

{
"ok": true,
"charged": true,
"recordType": "listing",
"searchTerm": "road bike",
"listingId": "1807545393723285",
"listingUrl": "https://www.facebook.com/marketplace/item/1807545393723285/",
"title": "Giant TCR C3 Road Bike. 600$ OBO. Full Carbon Frame + Fork. 700x 23c tires.",
"price": 600,
"priceFormatted": "$600",
"currency": "USD",
"originalPrice": 850,
"priceMin": null,
"priceMax": null,
"city": "Austin",
"state": "TX",
"locationName": "Austin, Texas",
"imageUrl": "https://scontent.fpei1-1.fna.fbcdn.net/v/t39.84726-6/818962247_1436233761733825_8678125269974170042_n.jpg?stp=...",
"videoUrl": null,
"postedAt": "2026-09-20T15:32:49.000Z",
"postedAtTimestamp": 1789918369,
"daysListed": 9,
"isSold": false,
"isPending": false,
"isLive": true,
"categoryId": "1658310421102081",
"deliveryTypes": ["IN_PERSON"],
"subtitle": null,
"fromGroup": null,
"scrapedAt": "2026-09-30T02:26:04.593Z"
}
FieldWhat it is
listingId, listingUrlThe item's id and permanent link. Stable, so use either as your key across runs.
price, priceFormatted, currencyThe asking price as a number, the exact text Facebook shows, and the currency code worked out from that text's symbol. price is null when the listing has none.
originalPriceThe crossed-out price when the seller has cut it, otherwise null. The row above dropped from 850 to 600.
priceMin, priceMaxFilled in only for listings priced as a range.
city, state, locationNameWhere the seller says the item is. state is empty in countries without one.
postedAt, postedAtTimestamp, daysListedWhen it was listed, as an ISO date and as epoch seconds, and how many days ago that was.
isSold, isPending, isLiveThe listing's status when the run read it. A search shows what is for sale now, so isSold is false on nearly every row.
deliveryTypesHow the seller will hand it over, such as IN_PERSON, PUBLIC_MEETUP or DOOR_PICKUP.
categoryIdFacebook's internal department id. Fine for grouping, but Facebook publishes no name for it, so none is made up here.
subtitle, fromGroupThe extra line on vehicle listings (mileage and so on), and the group name when the item was cross-posted from one. Null on most rows.
searchTermWhich of your terms found it.

๐Ÿงพ Reading the output

Three kinds of row can land in the dataset.

RowHow to spot itCharged
A listingcharged: trueyes
The sample row_sample: trueno
A diagnostic_diagnostic: true, with an errorCode and a details sentenceno

The sample row only appears when the input has no search terms and no links. It shows the shape of a real row and also says recordType: "listing", so filter on charged rather than on recordType to keep just the listings.

errorCodeWhat it means
NO_LOCATIONThe run had no place it could search, so nothing was searched. On a link's row it means that link's city couldn't be placed, so the run's own location was searched instead.
WRONG_LOCATIONFacebook didn't recognise the place and answered with somewhere else. Those listings were thrown away.
NO_RESULTSNothing for that term in that place. A narrow term, a tight price range, or a sort order used together with daysSinceListed can do it.
BLOCKEDFacebook wouldn't show that search this time. Running it again later usually works.
BAD_INPUTA link in startUrls isn't a Marketplace link.
NETWORK, TIME_BUDGET, CHARGE_ERROR and the restRare. The details sentence says what happened.

โ–ถ๏ธ How to run it

  1. Open Facebook Marketplace Scraper and click Try for free.
  2. Type what you're looking for into Search terms, one per line.
  3. Put the city in Location.
  4. Set Maximum rows. Under Filters, add a price range or Listed within the last N days if you want them.
  5. Click Start, then download the dataset as JSON, CSV or Excel, or read it from the API.

๐Ÿ’ฐ How much does it cost?

$0.40 per 1,000 listings, flat on every Apify plan.

You pay per listing row. The sample row and the diagnostic rows are never charged. A listing that two of your terms both found is charged once, and one thrown away because Facebook searched the wrong city isn't charged at all.

๐Ÿ’ก What people use it for

  • Resellers running the same few terms every morning with daysSinceListed set to 1, so each run holds only what went up since yesterday.
  • Pricing something before buying or listing it: take the median of price across two dozen local listings instead of guessing.
  • Finding sellers who have already come down. Every row with an originalPrice is one of them.
  • Keeping a spreadsheet of what's for sale in a category you trade in, instead of scrolling the feed by hand.

๐Ÿšง What it does not do

  • More than about 24 listings per search. That is Facebook's first page, and there is no paging past it. A bigger maxItems only helps if you add more terms.
  • Condition, category, sold only, exact phrase or radius filtering. Those fields are on the form but change nothing right now.
  • Seller names or item condition as columns. Facebook leaves both out of search results.
  • Shipped items only. Asked for those, Facebook's search here returns nothing.
  • Several cities for your typed search terms. location takes one place. To cover more cities in one run, paste a Marketplace link for each city into startUrls.
  • A radius you choose. Facebook decides how wide to look, and an Austin search can pull in towns more than 100 km away.
  • Listings only group members can see. You get what Facebook shows anyone.
  • Photo links that last. imageUrl points at Facebook's image server and stops working after a while, so download the photos you want to keep.

๐Ÿงญ Which marketplace scraper do you need?

If you wantUse
Facebook Marketplace listings for a search, in the cities you nameThis one
Classified ads from one Craigslist city and categoryCraigslist Scraper
Classified ads on Gumtree in the UKGumtree UK Scraper
What an item actually sold for on eBayeBay Sold Listings Scraper
Posts from a public Facebook group, buy-and-sell groups includedFacebook Groups Scraper

โ“ Questions people ask

Do I need a Facebook account? No. Nothing of yours is used unless you paste cookies into sessionCookies. Do that only if you want the run to use your own account and rate limit instead of the one the actor shares between everyone who runs it. Treat those values like a password: anyone holding them can act as you, and Facebook may sign the session out.

Why do I have to give a place? Marketplace only searches locally. With no place the run writes a free NO_LOCATION row and stops before searching anything.

Why did I get fewer rows than maxItems? Each search stops at about 24, the budget is split evenly between your terms, and a listing found twice counts once.

Why did a search come back empty? Look at the diagnostic row. NO_RESULTS means the filters were too tight for that place, WRONG_LOCATION means try the plain city name or the short name Facebook uses in its own links, and BLOCKED means try again later.

Can I run it every day? Yes. Nothing is kept between runs, so use listingId to spot what's new and postedAt to sort it.

Is scraping Marketplace legal? The listings are public, though photos and descriptions sometimes carry personal details, so keep what you need and think before republishing it. Apify's article on whether web scraping is legal is worth reading first. None of this is legal advice.

๐Ÿ†˜ If something breaks

Open the Issues tab on the actor page and send the input you used with the run ID. The diagnostic rows in the dataset usually name the reason already.