Facebook Marketplace Scraper - Prices & Price Drops, No Login
Pricing
from $0.62 / 1,000 listings
Facebook Marketplace Scraper - Prices & Price Drops, No Login
Scrape Facebook Marketplace listings by city, keyword, category and price without login: title, price, location, photos, post date, plus condition, description and all photos on request. New-listing and price-drop monitoring, market price summary. No seller data.
Pricing
from $0.62 / 1,000 listings
Rating
0.0
(0)
Developer
Cliqto Media
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
6 days ago
Last modified
Categories
Security
Limited permissionsShare
Facebook Marketplace Scraper collects public Facebook Marketplace listings by city and search words, without a Facebook login, and returns one row per listing with the price, photos, location, delivery options and a market price comparison.
Use it to watch a local market, find new listings and price drops, or export Marketplace prices to a spreadsheet. The smallest run (Pattaya, "motorbike", 10 listings) takes under 10 seconds and costs about $0.017 on the Free plan.
Table of contents
- What it does
- How it works
- Quick start
- Use cases
- Input
- Output
- Pricing
- Limits
- API, export and integrations
- Troubleshooting
- FAQ
- Related Actors
- Support
What it does
The Actor opens Facebook Marketplace as a logged-out visitor in the city you name, runs your search and saves the listings it finds: title, price (also in US dollars when Facebook shows it), photos, city, category, delivery options, posting time and a link to the listing. It can also open each listing page for the description, condition, exact distance and vehicle details.
For monitoring, it remembers what it saw before. A repeat run can return only new listings, or mark price drops, price rises and removed listings.
It never logs in and never saves seller names, profiles or contact details.
Good fit
- Watch a city for new listings of a product and get only the new ones on every scheduled run.
- Track price drops on used cars, motorbikes, phones or furniture you are following.
- Compare asking prices in one or several cities: every search gets a median price, and every listing shows how far below that median it is.
How it works
- You give a city and search words (or paste Marketplace links from your browser). Several cities and several search words are combined into separate searches.
- The Actor reads the public Marketplace search pages for each search, applies your filters (price, condition, delivery, age, availability) and drops reposts of the same item. If you asked for details, it also opens each listing page.
- It saves one Dataset row per listing, a market price summary per search (
MARKET_SUMMARY) and a run report (RUN_SUMMARY) with the status of every search. In monitor mode it also stores what it saw, so the next run can find new listings and price changes.
Quick start
-
Open the Input tab. City is prefilled with
pattaya(box 1). Any city name works, for examplelondonorlos angeles. -
Keep Search words =
motorbikeor type your own (box 2). -
Keep Max listings =
10from the form (box 3). If you leave it empty, the Actor saves up to 50 listings per search. -
Click Start.
-
Open the Output tab. Switch views with the tabs (box 1), check Title, Price and Currency (box 2) and Below median % (box 3).
Expected result: 10 motorbike listings from Pattaya with prices in Thai baht, links and photos, in under 10 seconds.
Use cases
| Buyer job | Input path | Output entity | Key fields | Next integration |
|---|---|---|---|---|
| Export listings for a city and product | city, query, maxItems | Listing | title, price, currency, url, postedAt | CSV or Excel export |
| Get only new listings on a schedule | onlyNew + Apify schedule | New listing | listingId, title, price, firstSeenAt | Slack or Notion via deliveryConnector |
| Track price drops and removed listings | trackChanges, monitorName | Changed listing | changeType, previousPrice, priceDropPercent | Webhook or Slack |
| Find underpriced items | query, priceMin, priceMax | Listing with market comparison | marketMedianPrice, belowMarketPercent | Spreadsheet |
| Compare markets across cities | cities, queries | Market summary per search | MARKET_SUMMARY: median, p25, p75, count | API |
| Read full listing pages | includeDetails or startUrls with item links | Detailed listing | description, condition, distanceKm, vehicle | Database |
Input
Input fields
A run needs a place (city, cities, locationId or a Marketplace link) and a search word (query, queries) or a category. Everything else is optional.
| Field | Plain name | Type | Required | Default / prefill | Allowed values | Effect | Example | Recommendation |
|---|---|---|---|---|---|---|---|---|
city | City | text | one place is required | prefill pattaya | city name | Where to search | london | Use the city name people use in English |
query | Search words | text | query or category | prefill motorbike | any words | What to search for | iphone 15 | Short words find more |
category | Category | select | no | none | 18 Marketplace categories, e.g. vehicles, electronics, propertyrentals | Search inside one category | vehicles | Can be used without query |
priceMin, priceMax | Price range | whole number | no | none | 0 or more, local currency | Keeps listings in this price range | 5000, 30000 | Use the city's currency |
maxItems | Max listings | whole number | no | default 50, prefill 10 | 1–5000 | Listings saved per search | 200 | Raise the run timeout for big runs |
onlyNew | Only new listings | yes/no | no | false | Returns only listings not seen in earlier runs | true | For scheduled runs | |
trackChanges | Track price drops and removals | yes/no | no | false | Marks new, price-down, price-up and removed listings | true | For price watching | |
includeUnchanged | Include unchanged listings | yes/no | no | false | With trackChanges, also saves listings that did not change | true | Only if you need the full list each time | |
monitorName | Monitor name | text | no | none | letters, digits, spaces, -, _ | Keeps this monitor's memory apart | pattaya-bikes | Use one name per monitor |
dedupeReposts | Skip reposts | yes/no | no | true | Drops the same item posted again | true | Keep it on | |
maxRemovedChecks | Max removal checks | whole number | no | 20 | 0–200 | How many missing listings are checked before being marked removed | 50 | Each check is paid |
includeDetails | Include details | yes/no | no | false | Opens each listing page for description, condition, distance, vehicle data | true | Costs more per listing | |
radiusKm | Radius (km) | whole number | no | none | 1–500 | Keeps listings within this distance of the city | 20 | Turns on details |
condition | Condition | list | no | any | new, used_like_new, used_good, used_fair | Item condition filter | ["new"] | |
delivery | Delivery | select | no | any | local_pick_up, shipping | Delivery filter | shipping | |
daysSinceListed | Listed within | select | no | any | 1, 7, 30 days | Marketplace age filter | 7 | |
maxAgeHours | Posted within (hours) | whole number | no | none | 1–8760 | Drops listings older than this | 48 | |
availability | Availability | select | no | available | available, sold | Active or sold listings | sold | |
strictQuery | Title must contain all words | yes/no | no | false | Drops listings whose title lacks any of your words | true | Facebook search is loose | |
sortBy | Sort | select | no | best_match | best_match, creation_time_descend, price_ascend, price_descend, distance_ascend | Order Facebook returns | creation_time_descend | Newest first for monitors |
cities | More cities | list | no | none | city names | Extra cities | ["bangkok", "chiang mai"] | Each city × word is one search |
queries | More search words | list | no | none | words | Extra search words | ["honda", "yamaha"] | |
startUrls | Marketplace links | list | no | none | facebook.com/marketplace search, category or item links | Runs your browser links; filters in the link are kept | https://www.facebook.com/marketplace/bangkok/search/?query=honda | Easiest way to copy a search |
locationId | Location id | text | no | none | numeric id or city slug from a Marketplace link | Exact Marketplace location | 112306758786227 | When a city name is ambiguous |
outputFormat | Row format | select | no | flat | flat, nested | Flat columns or grouped objects | nested | flat is best for spreadsheets |
deliveryConnector | Send results to | MCP connector | no | none | your connector | Posts a short summary after the run | See below | |
deliveryTarget | Notion page or channel | text | no | none | Notion page link or Slack channel ID | Where the summary goes |
Input field names used by other Marketplace scrapers also work: urls for startUrls, resultsLimit for maxItems, includeListingDetails or getListingDetails for includeDetails.
Interacting settings
| When | Input A | Input B | Effective behavior | Example | Cost/result effect |
|---|---|---|---|---|---|
| Several places and words | cities | queries | Every city × word pair is a separate search, 50 at most | 3 cities × 2 words = 6 searches | One search fee each; maxItems applies per search |
| Both monitor options | onlyNew | trackChanges | trackChanges wins: known listings are compared, not dropped | Unchanged listings are paid as cheap checks | |
| Radius filter | radiusKm | includeDetails | Radius needs the listing page, so details are read | radiusKm: 20 | Listings outside the radius are paid as page checks |
| Link with filters | startUrls | query, priceMin… | Filters written in the link are used for that link | …/search/?query=honda&maxPrice=50000 | |
| Item links | startUrls with /marketplace/item/… | Each item page is read, up to 500 per run | Charged as detailed listings |
Input examples
Smallest run
{"city": "pattaya","query": "motorbike","maxItems": 10}
Expected behavior: one search in Pattaya.
Expected output: 10 listings with title, price, currency, url, primaryImage.
Limit or cost note: under 10 seconds and $0.017 on Free.
New listings every morning
{"city": "los angeles","query": "couch","maxItems": 100,"onlyNew": true,"sortBy": "creation_time_descend","monitorName": "la-couches"}
Expected behavior: the first run saves up to 100 listings; later runs save only listings that were not there before.
Expected output: new listings with firstSeenAt.
Limit or cost note: listings already seen are skipped free; you pay the search fee and the new rows.
Price watch with details
{"city": "bangkok","query": "iphone 15","strictQuery": true,"trackChanges": true,"includeDetails": true,"maxItems": 50,"monitorName": "bkk-iphone"}
Expected behavior: saves listings with description and condition; later runs mark priceDown, priceUp, new and removed.
Expected output: changeType, previousPrice, priceDropPercent, condition, description.
Limit or cost note: detailed listings cost more; unchanged listings are paid as checks only.
Output
Output fields
These are the flat row fields (outputFormat: "flat"). With nested the same data is grouped into objects such as price and market.
| Field | Meaning | Type | Can be empty? | Example / enum | Source / notes |
|---|---|---|---|---|---|
listingId | Marketplace listing id | text | no | 1347713167500771 | |
url | Link to the listing | text | no | https://www.facebook.com/marketplace/item/…/ | |
title | Listing title | text | no | 2012 Honda Click 125 | As written by the seller |
price | Asking price | number | yes | 18900 | 0 when Facebook shows ฿0 (free or "ask for price"); placeholders like 9999999 are kept as the seller wrote them |
currency | Currency code | text | yes | THB | |
priceText | Price as shown | text | yes | ฿18,900 | |
priceUsd | Price in US dollars | number | yes | 556.2 | Only when Facebook shows it |
originalPrice | Earlier price shown by Facebook | number | yes | 21000 | When the seller lowered it |
location, city, state, country | Listing place | text | yes | Pattaya, TH | |
latitude, longitude, distanceKm | Coordinates and distance from the searched city | number | yes | 9.7 | With details |
category, categoryId | Marketplace category | text | yes | vehicles | category is empty when Facebook uses an id outside the 18 known categories; categoryId is still set |
condition | Item condition | text | yes | used_like_new | With details |
deliveryTypes, shippingOffered | Pickup or shipping | list / yes-no | yes | ["IN_PERSON"] | |
postedAt | When it was listed | date-time | yes | 2026-06-28T11:02:15.000Z | |
status | Listing status | text | no | active, sold, pending, removed | |
subtitle | Extra line under the title | text | yes | 20K km | Often mileage for vehicles |
primaryImage, images, hasVideo | Photos | link / list / yes-no | yes | Facebook image links expire after some days | |
description | Listing text | text | yes | With details | |
vehicle | Make, model, mileage, transmission, fuel, colours | object | yes | {"make":"Honda","model":"Forza",…} | Vehicle listings with details |
changeType | What changed since the last run | text | yes | new, priceDown, priceUp, removed, stillActive | Monitor mode only |
firstSeenAt, previousPrice, priceDropPercent | Monitor history | date-time / number | yes | 8.2 | Monitor mode only |
marketMedianPrice | Median price of this search | number | yes | 26900 | From the listings read in the search. Prices of 0 and 1, placeholders like 9999999 and prices over 50x the median are left out |
belowMarketPercent | How far below the median | number | yes | 29.7 | Only when at least 5 priced listings; empty for prices left out of the median. Negative means the price is above the median |
isRepost | Looks like a repost of an earlier item | yes/no | yes | null | Only in monitor mode (onlyNew or trackChanges) |
searchQuery, searchLocation, searchCategory | Which search found it | text | yes | motorbike, Pattaya | |
detailsStatus | Was the listing page read | text | no | not_requested, ok, gone, failed | |
fetchedAt | When the row was saved | date-time | no |
Output entities and surfaces
| Situation | Dataset/API/KVS/live view | Result shape | User action |
|---|---|---|---|
| Normal item | Dataset, views Listings, With details, Changes | One row per listing | Open, export or filter |
| Market prices | Key-value store MARKET_SUMMARY | Per search: currency, count, min, p25, median, p75, max, mean | Compare cities or products |
| Domain-empty result | Dataset empty, RUN_SUMMARY status NO_RESULTS | Search list with found: 0 | Try other words or a bigger city |
| Partial result | Rows saved, RUN_SUMMARY status PARTIAL with a reason (MAX_ITEMS, TIME_LIMIT, CHARGE_LIMIT, LOGIN_WALL, UNKNOWN_LOCATION, SOURCE_ERROR) | Saved rows are kept | Read the reason, then raise the limit or retry |
| Technical failure | RUN_SUMMARY status ERROR or INVALID_INPUT, run marked failed | Message in the summary and log | Fix the input or retry later |
Output example
{"listingId": "1347713167500771","url": "https://www.facebook.com/marketplace/item/1347713167500771/","title": "2012 Honda Click 125","price": 18900,"currency": "THB","priceText": "฿18,900","priceUsd": 556.2,"originalPrice": null,"city": "Pattaya","country": "TH","category": "vehicles","condition": null,"deliveryTypes": ["IN_PERSON"],"postedAt": "2026-06-28T11:02:15.000Z","status": "active","subtitle": "20K km","primaryImage": "https://scontent…fbcdn.net/…jpg","description": null,"changeType": null,"marketMedianPrice": 26900,"belowMarketPercent": 29.7,"isRepost": null,"searchQuery": "motorbike","searchLocation": "Pattaya","detailsStatus": "not_requested"}
This trimmed row comes from the smallest run above. null means Marketplace did not show that value on the search page: condition, description and coordinates come only with includeDetails, and monitor fields only with onlyNew or trackChanges.
Send results to Slack or Notion
Pick your connector in the optional deliveryConnector field. After the run saves its data, the Actor posts a short summary (up to 25 rows and a link to the full dataset) there. Put a Notion page link or a Slack channel ID in deliveryTarget: in Notion every run is added on top of that one page, so your workspace does not fill up with new pages. A delivery error never fails the run and costs nothing extra. Connect a service once in Apify Console → MCP connectors.
Pricing
Pricing unit
You pay per event. Apify platform usage is included: there is no separate compute charge and no start fee.
| Event | When it is charged | Free | Bronze | Silver | Gold and up |
|---|---|---|---|---|---|
search | Once per search (city × search words), after Facebook answered with a results page | $0.008 | $0.0072 | $0.0064 | $0.0056 |
listing | Each saved listing from search pages | $0.00089 | $0.000801 | $0.000712 | $0.000623 |
listing-details | Each saved listing with its page read (instead of listing, not on top) | $0.008 | $0.0072 | $0.0064 | $0.0056 |
listing-checked | Each unchanged listing confirmed in trackChanges mode | $0.0004 | $0.00036 | $0.00032 | $0.00028 |
listing-page-check | Each listing page Facebook answered that is not saved: a removal check, or a listing outside radiusKm | $0.008 | $0.0072 | $0.0064 | $0.0056 |
- A search that finds nothing, or where no listing passes your filters, costs only the search fee ($0.008 on Free).
- With
onlyNew, listings you already have are skipped free: a repeat run with nothing new costs only the search fee. - Removed listings found by a removal check are saved free; the check itself is paid.
- Invalid input fails before any search and costs nothing.
- A search that Facebook refused (login page, block, no answer after retries) or a city Facebook did not accept costs nothing.
- If your run's maximum charge is reached, the Actor stops, keeps what it saved and reports
PARTIALwithCHARGE_LIMIT.
Cost examples
Measured on real runs, Free plan prices.
| Scenario | Input scope | Expected item/event count | Base charge | Optional charge | Stop/cap behavior |
|---|---|---|---|---|---|
| Smallest run | Pattaya, "motorbike", 10 listings | 1 search + 10 listings | $0.017 | none | Under 10 s |
| Nothing found | Nonsense search words | 1 search | $0.008 | none | NO_RESULTS |
| Medium export | Los Angeles, "couch", 200 listings | 1 search + 200 listings | $0.186 | none | About 15 s |
| Details | 20 listings with includeDetails | 1 search + 20 detailed | $0.168 | none | About 25 s |
| Monitor repeat | onlyNew, 10 seen skipped, 10 new saved | 1 search + 10 listings | $0.017 | none | Seen listings free |
| Price watch, nothing changed | trackChanges, 98 known listings | 1 search + 98 checks | $0.047 | removal checks if any | About 15 s |
| Large export | 3 cities × 2 words, 1000 each | 6 searches + 3227 listings | $2.92 | none | About 8 min; raise the timeout |
One search with N listings, by plan:
| Plan | 10 listings | 100 listings | 1000 listings |
|---|---|---|---|
| Free | $0.017 | $0.097 | $0.898 |
| Bronze | $0.015 | $0.087 | $0.808 |
| Silver | $0.014 | $0.078 | $0.718 |
| Gold and up | $0.012 | $0.068 | $0.629 |
Limits
- Public listings only. The Actor never logs in, so anything Facebook shows only to signed-in users is not available, and no seller name, profile or contact is saved.
- Up to 50 searches per run (cities × search words), up to 5000 listings per search, up to 500 item links per run.
- The default run timeout is 5 minutes, enough for a few hundred listings. For thousands, raise the timeout in the run options; one run works for 30 minutes at most. When time runs out, saved rows are kept and the search is marked
PARTIALwithTIME_LIMIT. - Facebook decides which listings appear and in what order. A search can show fewer listings than the city has, and rows are not strictly sorted even with
sortBy. priceUsdappears only when Facebook shows a dollar price. Photo links are Facebook links that expire after some days; download photos you want to keep.- Monitor memory keeps up to 5000 listings per search, in a store named
facebook-marketplace-statein your own Apify account. - Description, condition, exact distance and vehicle details need
includeDetails(orradiusKm), which costs more per listing.
API, export and integrations
- API: start a run with the input JSON above through the Apify API or client libraries; read rows from the run's Dataset.
- Export: download the Dataset as JSON, CSV, Excel, XML or HTML from the Output tab or the API.
- Scheduling: create an Apify schedule with
onlyNewortrackChangesand amonitorName; each run continues from the previous one. - Webhooks / no-code: use an Apify webhook on run success to pass the Dataset to Make, Zapier, n8n or your own endpoint.
changeTypetells the next step what happened. - Slack / Notion: set
deliveryConnectoranddeliveryTarget(see Send results to Slack or Notion).
Use with AI agents (MCP)
- MCP server URL with only this Actor:
https://mcp.apify.com?tools=cliqtomedia/facebook-marketplace. - Smallest useful input:
{"city": "pattaya", "query": "motorbike", "maxItems": 10}. - Key output fields:
title(what is sold),priceandcurrency(asking price),url(listing link),belowMarketPercent(how much cheaper than the search median),changeType(new or changed, in monitor mode). - A small run takes under 10 seconds and costs about $0.017 on Free. Keep
maxItemssmall for quick answers; 50 searches per run at most.
Troubleshooting
No listings
Symptom: the run succeeds, the Dataset is empty, RUN_SUMMARY says NO_RESULTS.
Likely reason: Facebook has no listings for these words in this city, or your filters (strictQuery, price, condition, maxAgeHours) removed all of them.
Check: searches[].found in RUN_SUMMARY shows how many listings were read before filters.
Action: use shorter or English search words, turn off strictQuery, widen the price range or try a bigger city.
City not found
Symptom: the search is marked UNKNOWN_LOCATION.
Likely reason: Facebook has no Marketplace page under this city name.
Check: open Marketplace in your browser, pick the city and look at the link.
Action: paste that link into startUrls, or copy the number or slug after /marketplace/ into locationId.
Run stopped early
Symptom: PARTIAL with TIME_LIMIT.
Likely reason: the run timeout (5 minutes by default) ended before all listings were read.
Check: RUN_SUMMARY.searches[].pagesRead and the run duration.
Action: raise the timeout in the run options, lower maxItems or split the cities into several runs. Saved rows are kept.
Charge limit reached
Symptom: PARTIAL with CHARGE_LIMIT.
Likely reason: the maximum cost per run you set was reached.
Check: the run's charged events.
Action: raise the maximum charge or ask for fewer listings.
Facebook asked to log in
Symptom: PARTIAL or ERROR with LOGIN_WALL.
Likely reason: Facebook showed a login page instead of listings for this request.
Check: the run log names the search.
Action: run again later. The Actor never logs in, so it cannot get past this page.
Input rejected
Symptom: the run fails at once with INVALID_INPUT.
Likely reason: no place, no search word or category, a non-Marketplace link, or more than 50 searches.
Check: the message in the run log, for example "Add a search word (query) or a category".
Action: fix the field named in the message. Invalid runs cost nothing.
FAQ
Do I need a Facebook account or cookies?
No. The Actor reads Marketplace as a logged-out visitor. Do not give it your cookies or password.
Why is my run empty, and do I pay for it?
Facebook found nothing, or your filters removed everything. You pay only the search fee ($0.008 on Free). RUN_SUMMARY shows how many listings were read before filters.
Does it return every listing in the city?
No. It returns what Facebook shows a logged-out visitor for your search, up to maxItems. Use several search words or categories to cover more.
How do I get only new listings every day?
Turn on onlyNew, give the monitor a monitorName and run it on an Apify schedule. Listings you already have are skipped free.
Can I get seller names or phone numbers?
No. Seller data is never saved.
Which countries work?
Any city where Facebook Marketplace works. Prices come in the local currency, with priceUsd when Facebook shows it.
Related Actors
- Craigslist Scraper — the same kind of local listings and prices from Craigslist.
- OLX Listings Scraper — classified listings from OLX in Poland, Ukraine, Romania and more.
- eBay Sold Listings Scraper — sold prices on eBay, to check what an item really sells for.
Support
For a bug, question or feature request, open the Actor's Issues tab on Apify. Include the run ID, your input (without private data) and the status from RUN_SUMMARY. Never send tokens, cookies or passwords.


