Request a tool
All toolsAutomationsGuidesMCP serverRequest a toolPlatformsCategories
Facebook Marketplace Scraper icon

Facebook Marketplace Scraper

Scrape Facebook Marketplace listings by keyword and city. Rows carry title, price, currency, location, link, posted date, sold status.

239 runs on Apify $0.0004 per listing ($0.4 / 1,000)
Run this in the cloudRun on Apify →

Real Estate & Classifieds

How it works

  1. 1
    Open it on Apify

    Hit Run on Apify — it opens the tool in the cloud, no install.

  2. 2
    Set the inputs

    Adjust searchTerms, location, maxItems (sensible defaults are pre-filled).

  3. 3
    Click Run

    The tool runs on Apify’s cloud and collects the data for you.

  4. 4
    Export the results

    Download as JSON, CSV or Excel, or pipe straight into your app, Google Sheets, or an AI agent.

Pricing

$0.0004 per listing = $0.4 per 1,000

You are charged forWhenPrice
ListingOne Facebook Marketplace listing delivered to your dataset, with its title, price, currency, original price, location, listing link, primary photo, posting time, days listed, delivery options, category id and sold/pending status. Sample rows, diagnostics and listings already returned earlier in the same run are never charged.$0.0004

Pay-per-event pricing: you are billed per result, not per subscription. Billing is handled by Apify on your own account. These are the live Apify store prices, in effect since 2026-08-16, and they are what you are actually charged.

Inputs

FieldWhat it doesType
searchTermsWhat to look for on Marketplace. Up to 10 terms per run; the row budget below is shared evenly between them.array
locationWhere to search. A plain city name works ("Austin, TX", "Manchester", "Toronto"), so does a Marketplace city slug ("nyc", "la", "sanfrancisco"), and so does a raw "latitude,longitude" pair. Marketplace search is local, so this is required unless you set the coordinates below or paste a URL that carries them.string
maxItemsTotal listings to return across all search terms. The budget is shared evenly between the terms, so four terms and 40 rows gives you ten of each. Keep it low while you are testing - you pay per row.integer
minPriceOnly listings at or above this price, in the currency of the place you are searching. Leave empty for no lower bound.integer
maxPriceOnly listings at or below this price, in the currency of the place you are searching. Leave empty for no upper bound.integer
conditionNot applied at the moment. The search runs as if this were empty, so picking a condition does not narrow the listings that come back. It stays on the form so saved tasks that send it keep working. Facebook does not show an item's condition in search results, so there is no condition column in the output either.array
daysSinceListedOnly listings posted in the last N days, from 1 to 30. Facebook counts whole days, so a row's postedAt can be a little older than N days. Used together with a sort order, some searches come back empty. Leave empty for all listings.integer
sortByHow Facebook should order the results. Defaults to its own relevance ranking.string
availabilityNot applied at the moment. The search runs as if this were empty, so choosing Sold does not narrow the listings that come back: you get what is for sale now, and isSold is false on nearly every row. It stays on the form so saved tasks that send it keep working.string
exactMatchNot applied at the moment. The search runs as if this box were unticked, so Facebook matches your term the loose way whatever you choose here. It stays on the form so saved tasks that send it keep working.boolean
categoryNot applied at the moment. The search runs as if this were empty, so a category id does not narrow the listings that come back. To keep to one kind of item, say it in the search term. It stays on the form so saved tasks that send it keep working.string
startUrlsMarketplace search URLs copied straight from your browser, for example https://www.facebook.com/marketplace/nyc/search?query=road%20bike&minPrice=100. Up to 10 per run. The term, the place, the price range, the days-listed limit and the sort order are taken from the URL. A condition, category, radius, availability or exact-phrase setting in the URL is ignored, just as those fields are on this form, and so is a delivery method. Each URL is searched in the city it names, so URLs for different cities can share a run. A URL whose city the run can't place (a numeric Facebook location id, for example) falls back to the run's own location, and a free NO_LOCATION row says so. A filter you set in the fields above wins over the same filter in the URL.array
latitudeCentre the search on these exact coordinates instead of a place name, for example 30.2672. Set both latitude and longitude, or neither.string
longitudeCentre the search on these exact coordinates instead of a place name, for example -97.7431. Set both latitude and longitude, or neither.string
radiusKmNot applied at the moment. The search runs as if this were empty, and Facebook decides how wide to look around the place you give: an Austin search can bring back towns more than 100 km away. It stays on the form so saved tasks that send it keep working.integer
proxyUrlsLeave this empty for a normal run. Fill it in only if you want the traffic to leave through proxy servers you already pay for, one URL per line, in the form http://user:pass@host:port.array
sessionCookiesLeave this empty unless you need it. Runs are logged out by default and that is enough for public Facebook content. Facebook shows some things only to a signed-in account, and it limits how fast any one account may read; supplying your own cookie uses your account and your own rate limit, shared with nobody. In Chrome: open facebook.com while signed in, press F12, then Application > Cookies > https://www.facebook.com, and paste the values as "c_user=…; xs=…". One line per account. Treat these like a password: anyone with them can act as that account, and Facebook may sign the session out or restrict the account for automated use.array

What you get

A structured dataset — each result includes fields like:

searchTermlistingIdlistingUrltitlepricepriceFormattedcurrencyoriginalPricepriceMinpriceMaxcitystatelocationNameimageUrl

Export every run as JSON, CSV or Excel, or send it to your app, a database, Google Sheets, or an AI agent.

Related tools in Real Estate & Classifieds

Other ready-to-run tools in the same category — all pay-per-use on the Apify cloud.

Zillow Scraper iconReal Estate & Classifieds

Zillow Scraper

Scrape Zillow search results and full listing details: price, beds, baths, sqft, photos, price history, schools. No login or API key. $0.0008 per property.

1 use cases

Realtor.com Scraper iconReal Estate & Classifieds

Realtor.com Scraper

Realtor.com listings as JSON, by city, ZIP or county. Fields: address, price, beds, baths, sqft, year built, days on market, agent, broker. $0.68/1k.

Ready to run — no setup

Craigslist Scraper iconReal Estate & Classifieds

Craigslist Scraper

Scrape Craigslist listings by city, category and keyword: id, title, price, neighborhood, date, images and URL. No account or API key. $0.85 per 1,000.

1 use cases

Airbnb Listings Scraper iconTravel, Hotels & Events

Airbnb Listings Scraper

Scrape Airbnb listings by location, dates and guests. Get listing ID, name, room type, price, rating, reviews and host. No account, no API key.

Ready to run — no setup

Avito Listings Scraper iconReal Estate & Classifieds

Avito Listings Scraper

Scrape Avito.ru listings by keyword, category or city. Get id, title, price, seller name and type, publish date and photos. $0.30 per 1,000 listings.

1 use cases

See all Real Estate & Classifieds →

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.