Facebook Marketplace Scraper with Prices & New-Listing Alerts
Pricing
Pay per event
Facebook Marketplace Scraper with Prices & New-Listing Alerts
Search Facebook Marketplace by keyword, city, price, condition and age and get every listing as a row: price, town, posted time, sold flag, photos and the seller's description. Monitoring mode returns only new listings, for deal alerts, resale sourcing and price research.
Pricing
Pay per event
Rating
0.0
(0)
Developer
SR
Maintained by CommunityActor stats
0
Bookmarked
7
Total users
5
Monthly active users
16 days ago
Last modified
Categories
Share
Facebook Marketplace Scraper with New-Listing Alerts
This Facebook Marketplace scraper turns Marketplace searches into structured rows you can sort, filter and export: asking price as a number and as printed, the seller's town, when the item was posted, sold and pending flags, and optionally the seller's description, category and every photo. Search by keyword and city, apply the filters you use on Marketplace, or supply a Marketplace URL directly. Monitoring mode returns only listings that your monitor has not delivered before, so a scheduled run becomes an alert feed for new listings.
No Facebook login, no cookies and no account of your own are needed. Export the dataset as JSON, CSV or Excel, or read it through the Apify API from your own code.
What the Facebook Marketplace scraper returns
- Price as a number and as printed.
priceis numeric andpriceTextkeeps the original display. Zero is a real seller price and stays in your data. - Price drops.
wasPriceandwasPriceTextcarry the struck-through original when a seller has lowered the price. - The seller's town on every row, plus region code, location line and approximate coordinates when listing details are on. One city search routinely returns listings from many surrounding towns.
- Posted time as
listedAtEpochand as an ISO timestamp inlistedAt. - Sold, pending and live flags, so asking prices and completed sales can be told apart.
- Description, category chain and every photo when listing details are requested.
- Traceability. Each row echoes the
searchUrl,searchLocationandsearchQueryit came from. - A run summary in the key-value store with what was planned, fetched and returned, plus an
errorsrecord for anything that failed.
Facebook Marketplace scraper input
Use searchKeyword for one search term and location for one city slug or city ID. Both values come from the Marketplace search you want to read. A city slug such as amsterdam identifies a local market; Marketplace does not offer a worldwide search through this input. Set country to the two-letter country code of the market. This also determines the language in which the source is requested.
For several searches, use keywords and locations. Every keyword is paired with every location. A nonempty list replaces its corresponding single value: keywords replaces searchKeyword, and locations replaces location. You can plan at most 50 searches in one run. Results retain the order of the searches and are deduplicated by listing ID across the whole run.
The existing category input accepts a category slug from a Marketplace URL, such as vehicles, propertyrentals or apparel. Category browsing is currently unsupported: the tested category pages return no usable search feed, both alone and with a keyword. These requests finish with an empty dataset and a collection error. Use a keyword and city without category, or supply a Marketplace search URL. category is ignored when startUrls are supplied.
startUrls accepts Marketplace URLs as strings or objects containing a url. These direct URLs take precedence over the search builder. Their filters and paths are preserved. Use URLs that point to Facebook Marketplace. Category pages that do not expose a listing feed return an empty result with an error rather than unrelated listings.
The following input was used in a real run on 2 October 2026. It returned 12 listings and attempted details for the first eight. The lists selected Rotterdam and bakfiets, replacing the single city and keyword.
{"searchKeyword": "fiets","keywords": ["bakfiets"],"location": "utrecht","locations": ["rotterdam"],"country": "nl","sort": "newest","minPrice": 100,"maxPrice": 1500,"condition": ["used_good","used_like_new"],"daysSinceListed": 30,"availability": "in_stock","deliveryMethod": "local_pickup","radiusKm": 40,"exactMatch": false,"listingDetails": true,"allPhotos": true,"maxPagesPerUrl": 2,"maxListings": 12,"maxDetails": 8,"onlyNewListings": false,"retries": 4}
Filters and collection limits
sort supports best_match, newest, price_asc, price_desc and distance_asc. The default is best_match. minPrice and maxPrice set nonnegative price bounds in the market's currency. The minimum must not exceed the maximum. condition accepts new, used_like_new, used_good and used_fair. daysSinceListed accepts 1, 7 or 30 days.
availability defaults to in_stock; choose sold to request sold listings. deliveryMethod defaults to all, with local_pickup and shipping as alternatives. exactMatch defaults to false and requests phrase matching when enabled. Facebook determines the final matching and ranking. radiusKm is passed to the source, but Facebook has been observed to ignore it; do not rely on it to enforce a geographic boundary.
maxPagesPerUrl defaults to five pages and supports 1 through 40. maxListings defaults to 100 and caps delivered rows at a maximum of 5,000. The Actor follows available pages until the requested collection is complete or the source or run time limit prevents further collection. Check the summary and warnings when a collection is incomplete. Existing API handling of zero or null is preserved: page and retry limits use their defaults, while listing and detail limits omit their cap.
Output
Each dataset row describes one listing. The following excerpt is from the same real run as the input above; it shows selected fields without changing their values.
{"id": "1819312209252188","url": "https://www.facebook.com/marketplace/item/1819312209252188/","title": "Urban Arrow Family Regenhuif - Nieuw","price": 150,"priceText": "€ 150","currency": "EUR","city": "Bergeijk","listedAt": "2026-09-29T20:27:42Z","sellerName": null,"sellerId": null,"detailsFetched": true}
The original output fields remain available: id, url, title, price, priceText, currency, wasPrice, wasPriceText, city, stateCode, locationText, latitude, longitude, isSold, isLive, isPending, listedAtEpoch, listedAt, categoryId, deliveryTypes, isShippingOffered, imageUrl, sellerName, sellerId, searchUrl, searchLocation and searchQuery.
Detail rows can also contain description, inventoryCount, listingInventoryType, categorySlug, categoryName, categoryPath, photos and detailsFetched. Fields unavailable from the source may be null or absent. The asking price is numeric; zero is a real seller price. priceText retains the original formatted display. Currency is reported when the source provides it, and is not inferred from an ambiguous currency symbol. Additional fields include the collection timestamp fetched_at, the requested country and the 1-based result position.
The full row for that listing, with details and all photos requested, also carried stateCode NB, locationText Bergeijk, NB, approximate latitude and longitude, isSold: false, isLive: true, deliveryTypes: ["IN_PERSON"], categorySlug misc, the seller's description in Dutch and four photo URLs.
Listing details and photos
Enable listingDetails to request each listing's description, category information, approximate coordinates and available seller information. It defaults to false. Use maxDetails to limit how many delivered listings receive this enrichment. Without that limit, details are requested for all delivered listings. Enable allPhotos alongside details to collect the listing's own gallery. Neither option creates an additional billable event in the current price model.
Detail fields fill missing values in the search row. They do not overwrite values already supplied by the search result. A failed detail request keeps the search row and reports detailsFetched: false. Listings beyond maxDetails do not receive that field. Photo URLs can expire, so download images promptly if you need to retain them.
Monitoring and schedules
Set onlyNewListings to true to collect newly encountered listing IDs. Give each independent monitor a cacheKey. The default cacheStorageName is facebook-marketplace-seen, and an omitted cache key uses the shared default record. The existing monitoring history survives between runs. Only delivered listings are remembered, so results outside maxListings remain eligible for a later run.
The Actor keeps up to 50,000 IDs and removes the oldest first. Price edits do not make an existing ID new. Run a normal collection periodically if price changes matter. The summary reports stateStore, stateSaved, previous and current known-listing counts, and how many already known rows were skipped. If named storage is unavailable, stateStore reports run-default; that fallback does not retain history across runs.
Use cases for a Facebook Marketplace scraper
Deal alerts. Set maxPrice to what you would actually pay, sort by newest, enable onlyNewListings and schedule the run every fifteen minutes. The dataset only ever holds listings you have not seen, and an empty run bills only the start fee. Connect the run to an Apify integration or webhook to receive the alert by e-mail, Slack or your own endpoint.
Market value research. Collect a few hundred listings for one product in one market and take the median of price. That is the current asking market rather than a guide price, and listedAt lets you weight the most recent week more heavily.
Regional price comparison. Group rows by city and compare medians. Second-hand traders use this spread to decide where to buy and where to sell.
Sold-listing price history. Set availability to sold to collect listings that have left the market, rather than the ones still sitting on it.
Resale sourcing and supply tracking. Monitor a product keyword in several cities, count new listings per day and filter on deliveryTypes for listings that ship. Use keyword searches without category; category browsing is currently unsupported.
How it compares
Facebook does not offer a public Marketplace search API for buyers: its Marketplace APIs are for commerce partners that publish their own inventory. Your options are to copy listings by hand, to run an open-source script and maintain it yourself whenever Facebook changes its pages, or to use a hosted scraper. The table compares this Actor with the two Store Actors that most people use, using the public price lists on 2 October 2026.
| this Actor | apify/facebook-marketplace-scraper | curious_coder/facebook-marketplace | |
|---|---|---|---|
| Per 1,000 listings, FREE plan | $0.40 | $6.20 | $0.50 |
| Per 1,000 listings, paid plans | $0.35 | $5.00 to $0.80 | $0.50 |
| Separate charge for listing details | no | yes, same as a listing | yes, $1.00 per 1,000 |
| Run-start fee | $0.00005 | none | $0.00005 |
| Keyword and city search builder | yes | no, URLs only | yes |
| Monitoring mode for new listings | yes | no | yes |
| Sold-listing filter as an input field | yes | no, URLs only | yes |
Price drops as separate fields (wasPrice) | yes | not documented | not documented |
Those Actors have far more users today, which is a real signal of trust. What this Actor offers is the same core data at a lower price, details without a second charge, and a monitoring mode built for schedules.
Pricing
The existing price model is unchanged. The run-start event costs $0.00005 per run. A delivered listing costs $0.0004 on the FREE tier, or $0.00035 on BRONZE through DIAMOND. That is $0.40 or $0.35 per 1,000 delivered listings, plus the run-start fee. The current model has no separate detail event. Empty searches and monitoring runs with nothing new bill only the start fee.
Users without a paid Apify plan receive up to 10 rows per run. Only delivered rows are charged. Set smaller maxListings and maxDetails when you need a limited sample. The Actor records its run summary and any collection errors in the default key-value store.
FAQ
Does a monitor return a listing again after its price changes?
No. Monitoring identifies listings by ID, not by price or posted timestamp. Use a normal run to inspect changes to listings you already know.
Why can currency or seller information be missing?
The search feed does not always expose these values. Details can fill them when the listing page provides them. Missing public information is not invented.
Are listing details charged separately?
No. The current live price model charges the run-start event and delivered listings. Details and photos enrich those listings without a separate detail event.
What happens if a search or detail page is unavailable?
The Actor retries up to retries attempts, with a default of four. Other successful searches remain in the dataset. A failed detail keeps its original search row. If Facebook stops serving further pages of a search, the listings already collected are kept and the run reports a warning instead of failing. Check the summary, warnings and errors for incomplete work.
Is there a Facebook Marketplace API I can use instead?
Not for searching other people's listings. Facebook's Marketplace APIs serve commerce partners that list their own products. This Actor gives you the public search results as a dataset that you can read through the Apify API, which is how most users run it as a Facebook Marketplace API.
Do I need a Facebook account or cookies?
No. The Actor reads the public Marketplace pages that a signed-out visitor sees. Your own Facebook account is never used and never at risk.
Can I get every listing in a city?
Facebook publishes no result count and keeps offering another page for as long as you ask, so no tool can promise every listing. Depth is a budget choice: raise maxPagesPerUrl and maxListings, and cover a market with several keywords, cities or price bands. Rows are deduplicated by listing ID across all searches in a run.
Which countries does it support?
Any Marketplace market that Facebook serves to a signed-out visitor. Set country to the market's two-letter code and use that market's city slug or ID in location.