Facebook Marketplace API & Scraper
The Facebook Marketplace API returns Marketplace's public local classifieds as clean JSON, one metro at a time.
🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.
search takes a keyword and a location and returns listings with id, title, price as a number next to the price the site prints, the seller's earlier price when it was lowered, the city and state the item sits in, when it was posted, whether it is sold or pending, its photo and how it changes hands. category browses any of Marketplace's 17 categories - vehicles, home sales, property rentals, electronics, apparel, free stuff and the rest - with the same fields and the same filters. listing returns the full ad: the seller's description, the condition they graded it, the category path, every photo with its dimensions, the city-level coordinates, the current status, and the seller themselves - name, Marketplace profile link, profile photo, join date and 5-star rating - whenever Facebook includes them in the response. Marketplace is city-scoped, so location is the axis that matters: 47 US metros are supported by name and any other Facebook city by its id, and the same query in five metros returned zero listing ids in common with New York. Filters were checked on the values they return, not on the fact that results moved: a 500-2000 price range returned 13 of 13 listings inside it where the unfiltered page had 6 of 15, and a one-day recency filter returned 15 of 15 posted within two days against 3 of 15. On 2026-09-23, 42 live calls across the three actions returned 42 answers, and 8 listings checked against their own pages matched on id, price, title and sold status 8 of 8. One ReefAPI key, the standard { ok, data, meta, error } envelope.
What an unknown city gives you - and why this API refuses it
Facebook does not reject a place it does not recognise. It quietly answers with a different metro's listings, and nothing in the page says so. The spelling philadelphia is a real example: it is not the Marketplace slug, and it resolves somewhere else - differently on different days. This API verifies the location Facebook resolved against the one you asked for, and returns nothing rather than another city's inventory. Every response names the location that was actually searched.
| Location asked for (measured 2026-09-23) | What Facebook answered with | What this API does |
|---|---|---|
| philly | Philadelphia, Pennsylvania | Returns Philadelphia listings - this is the working slug |
| philadelphia | Chicago, Illinois on one run, Greenwood, Mississippi on another | Rejected as an unknown location, with philly suggested |
| sacramento | Wesley Chapel, Florida | Rejected as an unknown location |
| a misspelt or invented city | A full page of real listings from whichever metro it landed on | Rejected as an unknown location |
| nyc, la, chicago, houston, vegas and 42 more | The metro itself, confirmed by its own city id | Returns the listings, and reports location.name and location.id |
The same iphone search in la, chicago, houston, philly and vegas returned zero listing ids in common with New York, and the cities on the rows were local to each metro. 47 metros were each verified against the city id Facebook itself reports; any other Facebook city can be passed as that numeric id and is checked the same way.
Real request and response JSON
Captured from the indexed primary action, search, on .
{
"method": "POST",
"url": "https://api.reefapi.com/facebook-marketplace/v1/search",
"headers": {
"x-api-key": "$REEF_KEY",
"content-type": "application/json"
},
"body": {
"query": "iphone",
"location": "nyc"
}
}{
"ok": true,
"meta": {
"api": "facebook-marketplace",
"endpoint": "search",
"mode": "live",
"latency_ms": 1723.5,
"record_count": 15,
"bytes": 646362,
"cache_hit": false,
"pagination": {
"page_size": 15,
"source_has_more": true
},
"upstream_requests": 1,
"charged_credits": 3,
"version": "0.1.0"
},
"data": {
"results": [
{
"listing_id": "1101688325746923",
"title": "iPhone 17",
"custom_title": null,
"subtitles": [],
"url": "https://www.facebook.com/marketplace/item/1101688325746923/",
"price": 700,
"price_formatted": "$700",
"price_was": null,
"price_min": null,
"price_max": null,
"currency": "USD",
"city": "New York",
"state": "NY",
"city_id": "108424279189115",
"posted_at": "2026-09-23T19:44:52Z",
"is_sold": false,
"is_pending": false,
"is_live": true,
"category_id": "1557869527812749",
"image": "https://scontent-mia3-1.xx.fbcdn.net/v/t39.84726-6/820206050_2344237786341263_3830755337822045726_n.jpg?stp=c43.0.260.260a_dst-jpg_p261x260_tt6&_nc_cat=110&ccb=1-7&_nc_sid=92e707&_nc_ohc=WaPO0gCfqUAQ7kNvwECbpI0&_nc_oc=AdrEMxNhNia0ly01fcOR-V6IF51Gte0vi8TBkf8v4pcArTYaxsgQ1xp7Mzb0_K84Pjw&_nc_zt=14&_nc_ht=scontent-mia3-1.xx&_nc_gid=ozt-NX1jKZhGiWia9AuPPg&_nc_ss=79289&oh=00_AQK4gI9xaSAa1gHbdVAdNlczBjLWBxTZrb7SpalgaMgjvQ&oe=6AB9EBEA",
"has_video": false,
"delivery_types": [
"IN_PERSON"
],
"listing_type": "GroupCommerceProductItem"
},
{
"listing_id": "29708685485401601",
"title": "iPhone 16 pro 256gb",
"custom_title": null,
"subtitles": [],
"url": "https://www.facebook.com/marketplace/item/29708685485401601/",
"price": 450,
"price_formatted": "$450",
"price_was": null,
"price_min": null,
"price_max": null,
"currency": "USD",
"city": "New York",
"state": "NY",
"city_id": "108424279189115",
"posted_at": "2026-09-23T19:10:08Z",
"is_sold": false,
"is_pending": false,
"is_live": true,
"category_id": "1557869527812749",
"image": "https://scontent-mia5-1.xx.fbcdn.net/v/t39.84726-6/818102050_848624618273918_3653634437020635816_n.jpg?stp=c0.50.261.261a_dst-jpg_p261x260_tt6&_nc_cat=104&ccb=1-7&_nc_sid=92e707&_nc_ohc=NwRYvOisd0QQ7kNvwHMaAln&_nc_oc=AdpmWJpnWc3SImN453e9vXD4jeIgGfEN0quJ6-lUMMQjgDypn6-zR_uKxYpRP_qFI4M&_nc_zt=14&_nc_ht=scontent-mia5-1.xx&_nc_gid=ozt-NX1jKZhGiWia9AuPPg&_nc_ss=79289&oh=00_AQLSi13_Iajz0-zTfokn-if672rIcnBQQPflaNIFINrHSQ&oe=6AB9FBCE",
"has_video": true,
"delivery_types": [
"IN_PERSON",
"PUBLIC_MEETUP",
"DOOR_PICKUP"
],
"listing_type": "GroupCommerceProductItem"
},
{
"listing_id": "1788121532189152",
"title": "iPhone 13 Pro Max",
"custom_title": null,
"subtitles": [],
"url": "https://www.facebook.com/marketplace/item/1788121532189152/",
"price": 250,
"price_formatted": "$250",
"price_was": null,
"price_min": null,
"price_max": null,
"currency": "USD",
"city": "New York",
"state": "NY",
"city_id": "108424279189115",
"posted_at": "2026-08-22T11:48:10Z",
"is_sold": false,
"is_pending": false,
"is_live": true,
"category_id": "1557869527812749",
"image": "https://scontent-mia3-1.xx.fbcdn.net/v/t39.84726-6/782924707_4308575752786194_5900536050177428487_n.jpg?stp=c0.42.261.261a_dst-jpg_p261x260_tt6&_nc_cat=110&ccb=1-7&_nc_sid=92e707&_nc_ohc=kd9VCWTt6K4Q7kNvwFkfI-i&_nc_oc=AdrBLWRTOHuL-eQ_XkIwxHWLz8yGU7ZCwX12wJjzormkiKBOvQP3lBTEcpHdMHPiiGg&_nc_zt=14&_nc_ht=scontent-mia3-1.xx&_nc_gid=ozt-NX1jKZhGiWia9AuPPg&_nc_ss=79289&oh=00_AQIxqDxgiDzo0y-SM765AcEXea-aw7uByp2p1XRQ2rnF_A&oe=6ABA047D",
"has_video": false,
"delivery_types": [
"IN_PERSON"
],
"listing_type": "GroupCommerceProductItem"
}
],
"count": 15,
"total_results": null,
"source_has_more": true,
"location": {
"name": "New York, New York",
"id": "108424279189115"
},
"currency": "USD",
"filters_applied": [],
"dropped_non_listing_tiles": 0,
"query": "iphone"
}
}What the Facebook Marketplace API does
| Action | Description | Concrete use case | Key params |
|---|---|---|---|
| search | Search one metro's Marketplace listings by keyword: listing id, title, price (with the seller's earlier price when it was lowered), the city and state the item sits in, when it was posted, whether it is sold or pending, its photo and how it changes hands. Filter by price range, how recently it was posted, condition, delivery method and pending status; order by best match, newest, price or distance. The response always names the location Facebook actually resolved. | Pricing teams call search to search one metro's Marketplace listings by keyword. | query, location, price_min, price_max, days_listed, ... |
| category | Browse one of Facebook Marketplace's 17 categories inside a metro — vehicles, property for sale, property rentals, electronics, apparel, free stuff and the rest — with the same row shape and the same filters as search. | Marketplace operators call category to get browse one of Facebook Marketplace's 17 categories inside a metro. | category, location, price_min, price_max, days_listed, ... |
| listing | The full listing by id or URL: title, the seller's full description, price and currency, the condition they graded it, the category path, every photo with its dimensions, the city it sits in with the city-level coordinates the site rounds to, when it was posted, whether it is available, pending or sold, how it can be delivered, and the seller as the public listing shows them: name, profile link, profile photo, the date they joined, and their 5-star rating with its count. | Catalog enrichment teams call listing to get the full listing by id or URL. | listing_id, seller_attempts, max_rotations |
Call search from your stack
curl -X POST https://api.reefapi.com/facebook-marketplace/v1/search \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"query":"iphone","location":"nyc"}'import requests
r = requests.post(
"https://api.reefapi.com/facebook-marketplace/v1/search",
headers={"x-api-key": REEF_KEY},
json={
"query": "iphone",
"location": "nyc"
},
)
print(r.json()["data"])const res = await fetch("https://api.reefapi.com/facebook-marketplace/v1/search", {
method: "POST",
headers: {
"x-api-key": process.env.REEF_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"query": "iphone",
"location": "nyc"
}),
});
const { ok, data, meta, error } = await res.json();Ask your MCP-connected assistant: call reefapi.facebook-marketplace.search with {"query":"iphone","location":"nyc"}.Who uses this API and why
- Resale and reseller tools track local second-hand prices for phones, consoles, furniture and bikes across several metros at once, using the same keyword per city and the price the listing actually publishes.
- Used-car and property teams browse the vehicles, home sales and property rentals categories in one metro and read each listing's description, photos and posting date.
- Deal-hunting and arbitrage products watch newly posted listings with sort newest and a one-day recency filter, then re-check each id later to see whether it went pending or sold.
- Local-market researchers measure how supply and asking prices differ between metros, using the resolved location every response reports rather than assuming the city they asked for.
- Outreach and lead tools pull the seller behind a listing - name, Marketplace profile link, join date and rating - to reach the people actually selling a category in a given metro.
Questions developers ask before integrating
Which locations does the API cover?
47 US metros by name - nyc, la, chicago, houston, philly, vegas, sanfrancisco, seattle, miami, boston, denver, atlanta, dallas, phoenix, sandiego, austin, portland, detroit, minneapolis, sanantonio and 27 more - plus any other Facebook Marketplace city by its numeric id, which every response returns as location.id. Each of the 47 was checked against the city id Facebook reports for it.
Why does an unknown city return an error instead of results?
Because the alternative is worse. Facebook answers a city it does not recognise with a full page of real listings from somewhere else, and says nothing about the substitution. Measured on 2026-09-23, philadelphia resolved to Chicago on one run and to Greenwood, Mississippi on another. This API checks the location Facebook resolved against the one you asked for and returns an error rather than another metro's inventory.
How many listings come back per call?
Between 8 and 25 for a keyword search and 24 for a category page, depending on the metro and the query; asking for a non-default order such as newest tends to return the fuller page. One page is returned per call - Marketplace's public pages do not offer a next page to follow, and the response says with source_has_more whether Facebook indicates more exist.
Can I filter by distance or radius?
No, and the honest reason is that Marketplace does not offer it on its public pages. Radius was tested in five different forms and none of them changed the results beyond the page's own run-to-run variation, because the radius is a per-viewer setting rather than part of the address. The location is the geographic control, and it works: five metros returned zero listing ids in common with New York. Listings do carry their own city and state, and the full listing adds city-level coordinates.
Which filters actually work?
Price range, how recently a listing was posted (1, 7 or 30 days), condition (new, like new, good, fair), delivery method (local pickup or shipped), pending status, and ordering by best match, newest, price or distance. Each was checked on the values returned: a 500-2000 range gave 13 of 13 listings inside it against 6 of 15 unfiltered, a one-day filter gave 15 of 15 posted within two days against 3 of 15, and price ordering came back strictly monotonic.
Does it tell me whether a listing is still available?
Yes. Every row carries is_sold, is_pending and is_live, and the full listing adds the status Facebook shows, such as AVAILABLE or PENDING. Note that Facebook's own pending filter means a sale is in progress, not that the item is sold - the two are returned as separate fields so you do not have to infer one from the other.
Does it return the seller?
Yes, whatever the public listing shows: their name, a link to their Marketplace profile, their profile photo, the date they joined and their 5-star rating with the number of ratings behind it. The catch is how often Facebook includes it - measured on 2026-09-23, only about one public listing response in ten carries the seller, at random, and the same listing can carry it on one read and not the next. seller_attempts asks the API to read the listing again until it appears (0 of 9 listings had it on the first read, 3 of 9 within six), and every answer reports seller_available and how many reads it used, so you are never guessing.
Why is a seller's rating sometimes null instead of a number?
Because a seller can keep their score private, and Facebook publishes a hidden score as 0 out of 0 ratings rather than leaving it out. Passing that through would label a seller who simply hides their rating as a zero-star seller, so a zero over zero ratings comes back as null with ratings_are_private true. Where the same person's combined buyer-and-seller score is still public it is returned as combined_rating - on one measured seller that was a genuine 4.9 from 18 ratings while their seller-only score was hidden.
What about a seller's phone number or address?
Not published on this surface. dealership_name, seller_phone, seller_website and listing_address are dealer fields that exist on the listing and were empty on all 30 listings checked, including 5 vehicles, so they come back null rather than being hidden from you. Badges are more useful and far more common: seller_badge_summary, such as 'Very Responsive on Marketplace' or 'Highly rated on Marketplace', was present on 7 of 9 listings.
How many results are there in total?
Facebook does not publish a result count anywhere on these pages, so total_results is null rather than a number we invented. count tells you how many rows this call returned, and source_has_more reports whether Facebook indicates there are more beyond them.
What is the Facebook Marketplace API?
Facebook Marketplace API is a ReefAPI endpoint group for local classifieds in 47 us metros: prices, condition, photos, the seller and whether it is still available. It returns live JSON through POST requests under /facebook-marketplace/v1.
Is the Facebook Marketplace API free to try?
Yes. ReefAPI starts with 1,000 free credits, no card required. Facebook Marketplace calls use the same shared credit balance as every other ReefAPI engine.
Do I need a Facebook Marketplace login or account?
No login to Facebook Marketplace is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the Facebook Marketplace data?
The page example is captured from a live search call, and production requests fetch live data through ReefAPI rather than a static sample.