Facebook Marketplace Scraper
Pricing
$19.99/month + usage
Facebook Marketplace Scraper
Extract product listings from Facebook Marketplace with ease! This actor scrapes titles, prices, descriptions, seller info, locations, images, and post URLs. Perfect for market research, price monitoring, competitor analysis, or lead generation from Facebook Marketplace listings.
Pricing
$19.99/month + usage
Rating
5.0
(1)
Developer
Scraper Engine
Maintained by CommunityActor stats
3
Bookmarked
139
Total users
1
Monthly active users
9 days ago
Last modified
Categories
Share
Facebook Marketplace Scraper — Prices, Photos and Listing Details
The Facebook Marketplace Scraper pulls structured data out of public Marketplace search results: listing title, price, location, and photos, plus condition, description, and category when deep mode is on. Feed it one or more Marketplace search URLs and it returns typed JSON — one row per listing, ready to export as JSON, CSV, or Excel, or pull through the Apify API. No Facebook account or login needed. Open the Actor in Apify Console and start your first run in minutes.
What is Facebook Marketplace Scraper?
Facebook Marketplace Scraper is an Apify Actor that turns a Facebook Marketplace search URL into a structured dataset of listings — title, price, photos, and location from the search results, plus the full detail-page record (condition, description, structured attributes, coordinates) when deep mode is enabled. It runs entirely logged-out: no Facebook account, cookies, or session token from the user is required, since the Actor bootstraps its own guest session directly against Facebook's public pages. It's built for resellers, market researchers, and developers who want Marketplace listing data as clean JSON instead of copying it out of a browser tab by hand.
What Facebook Marketplace listing data is publicly available to scrape?
Everything below is visible to any logged-out visitor who opens a Marketplace search page or a listing's own detail page — nothing here requires a Facebook account.
| Data Category | Publicly Available | Restricted behind Facebook login / Messenger |
|---|---|---|
| Listing title, price & currency | Yes — search results and detail page | — |
| Photos and video | Yes — full gallery on the detail page | — |
| Condition, category & structured attributes | Yes — detail page (deep mode) | — |
| Description text | Yes — detail page (deep mode) | — |
| Approximate location (city/state, map coordinates) | Yes — shown on search and detail page | Exact street address — Facebook never shows this to anyone |
| Delivery / shipping options | Yes | — |
| Seller's public name and listing profile link | Yes — attached to the listing node | Seller phone number or direct contact — only via Messenger, which requires a Facebook login |
| Deep, unlimited pagination and saved searches | Partial — several pages of results | Facebook prompts a login wall after extended browsing |
Facebook Marketplace Scraper only returns publicly visible data — what any visitor sees. Nothing behind a login wall.
What data can I extract with Facebook Marketplace Scraper?
Facebook Marketplace Scraper returns one flat JSON row per listing. The exact field set depends on the deepScrape input: deep mode (the default) returns the full detail-page record; quick mode returns the lighter search-result record. Both are documented in full below — nothing is invented or padded.
Deep mode fields (deepScrape: true, default) — full listing detail
| Field Name | Description |
|---|---|
facebookUrl | The Marketplace search URL this listing was found under |
id | Facebook's internal listing ID |
itemUrl | Direct URL to the listing's detail page |
listingTitle | Listing title |
description.text | Full listing description text from the detail page |
condition | Human-readable condition label (e.g. "Used - good", "New") |
listingCategoryId | Facebook's internal Marketplace category ID |
listingAttributes | Array of structured spec objects (attribute_name, label, value) — brand, size, make/model, etc. |
listingPrice | Price object: formatted_amount_zeros_stripped, amount, amount_with_offset_in_currency, currency |
strikethroughPrice | Original (crossed-out) price, if the listing shows a discount |
location | { latitude, longitude } map coordinates for the listing |
locationText | Human-readable city/state string |
deliveryTypes | Array of delivery/shipping options the seller offers |
listingPhotos | Full photo array, each with image.uri, width, height |
primaryListingPhoto | The single cover photo shown in search results |
listingVideo | Video attachment(s), if the listing has any |
timestamp | Listing creation time, ISO 8601 |
isSold / isPending / isLive / isHidden | Listing status flags |
isViewerSeller | Always false for a logged-out scrape (no viewer identity) |
customSubTitlesWithRenderingFlags | Extra rendering metadata Facebook attaches to some listings |
Quick mode fields (deepScrape: false) — search-result record
| Field Name | Description |
|---|---|
facebookUrl | The Marketplace search URL this listing was found under |
listingUrl | Direct URL to the listing's detail page |
id | Facebook's internal listing ID |
marketplace_listing_title / custom_title | Listing title as shown in search results |
listing_price | Price object: formatted_amount, amount, amount_with_offset_in_currency |
strikethrough_price, comparable_price, comparable_price_type | Discount and price-comparison signals shown on some listings |
min_listing_price / max_listing_price | Price range, for listings sold as a range |
location | { reverse_geocode: { city, state, city_page } } |
marketplace_listing_category_id | Facebook's internal Marketplace category ID |
marketplace_listing_seller | Seller node attached to the listing (public name / profile link, as Facebook exposes it) |
delivery_types | Array of delivery/shipping options |
primary_listing_photo | Cover photo (photo_image_url) |
listing_video, parent_listing, origin_group | Video attachment and listing-grouping metadata |
is_sold / is_pending / is_live / is_hidden / is_viewer_seller | Listing status flags |
custom_sub_titles_with_rendering_flags | Extra rendering metadata Facebook attaches to some listings |
🤖 Add-on: Need additional Facebook data?
Pair this with Facebook URL → ID Scraper to resolve a seller's profile link into a stable Facebook ID before cross-referencing it elsewhere, or run Facebook Posts Scraper against that same seller's Page to see their public posting activity. If a seller is also running paid promotions, Facebook Ads Library Scraper & Creative Media pulls their ad creatives as a separate dataset.
Why not build this yourself?
Meta does not publish a public API for third-party Marketplace listing search — the Graph API and Marketing API cover Pages, Ads, and app data, not C2C Marketplace listings. Building your own scraper means solving three ongoing problems: Facebook rotates the internal GraphQL document IDs and session tokens (lsd, fb_dtsg) that every request depends on, so a hardcoded scraper breaks whenever Facebook ships new frontend code; logged-out requests without a warmed guest cookie and a residential exit IP are routinely blocked with 403/429 responses; and running a reliable residential proxy pool with retry and IP-rotation logic is its own ongoing infrastructure cost. Facebook Marketplace Scraper handles all three by re-discovering the doc ID and session tokens from Facebook's own live HTML/JS on every run, and by always routing through Apify's residential proxy with automatic fresh-IP retries.
How to use Facebook Marketplace Scraper
Facebook Marketplace Scraper is published on the Apify platform and runs from the Apify Console (or via the Apify API) — no separate signup or credentials beyond your Apify account are needed.
- Open Facebook Marketplace Scraper on its Apify Console page.
- Paste one or more Facebook Marketplace search URLs into the required
urlsfield. - Set
count(listings to collect per URL —0for unlimited) and toggledeepScrapefor full detail vs. faster search-result rows. - Click Start.
- Open Storage/Output to browse the dataset, or export it as JSON, CSV, or Excel, or pull it via the Apify API.
How to scale to bulk Facebook Marketplace listing extraction
The urls field is an array, so a single run can hold many Marketplace search URLs at once — different queries, cities, or categories — and each one is paginated independently up to your count cap. There's no separate "bulk" input mode; scaling up simply means adding more lines to urls (or scheduling repeated runs for ongoing monitoring), not restructuring the input.
What can you do with Facebook Marketplace listing data?
- A reseller sourcing inventory uses
listingPriceandconditionto shortlist underpriced used items worth a closer look before making an offer. - A market analyst tracking a category uses
listingCategoryIdandtimestampacross repeated runs to chart how asking prices move over time. - A classifieds aggregator uses
locationTextandlistingPhotosto rebuild a searchable local-marketplace feed on their own site. - A product researcher uses
descriptionandlistingAttributesto see what condition, specs, and price sellers are actually listing comparable items at. - An AI agent building a deal-finder feeds
listingTitle,description, andlistingPriceinto an LLM prompt to rank listings by value and flag ones where the price and description don't line up.
How does Facebook Marketplace Scraper handle rate limits and blocking?
Every request is routed through Apify's residential proxy group — logged-out Marketplace traffic reliably blocks datacenter IPs, so there's no datacenter fallback tier. Bootstrapping a run (loading the search page and discovering the current GraphQL doc ID) is retried up to 4 times, and each attempt mints a brand-new proxy session ID so a single dead or blocked exit IP doesn't fail every retry identically. Before the first real request, the Actor warms up a guest datr cookie against facebook.com so later requests carry a normal browser identity rather than arriving cold. On every run it also re-extracts that page's live lsd/fb_dtsg session tokens from the bootstrapped HTML, since a stale token is what makes GraphQL calls silently return nothing. Detail-page (PDP) requests in deep mode retry up to 3 times with increasing backoff on a non-200 response or malformed JSON. If Facebook blocks the bootstrap across all attempts, the run still finishes successfully with an empty dataset rather than failing outright — re-running typically succeeds once a fresh residential IP is assigned.
⬇️ Input
| Parameter | Required | Type | Description | Example Value |
|---|---|---|---|---|
urls | Yes | array | One or more Facebook Marketplace search URLs to scrape. | ["https://www.facebook.com/marketplace/108479165840750/search/?query=phone&exact=false"] |
count | No | integer | Max listings to collect per URL. Default 20. Use 0 for unlimited. | 20 |
deepScrape | No | boolean | true (default) fetches each listing's detail page for the full field set; false returns faster, search-result-only fields. | true |
Example input
{"urls": ["https://www.facebook.com/marketplace/108479165840750/search/?query=phone&exact=false"],"count": 20,"deepScrape": true}
⬆️ Output
Facebook Marketplace Scraper pushes one flat, typed JSON row per listing to the run's default dataset — the schema is consistent across runs for a given deepScrape setting. Export directly from the Storage/Output tab as JSON, CSV, or Excel, or read it through the Apify API/SDK. Billing is pay-per-event: each row saved to the dataset charges the row_result event; a run that finds nothing (e.g. a blocked bootstrap) charges nothing.
Example output
{"facebookUrl": "https://www.facebook.com/marketplace/108479165840750/search/?query=phone","id": "1976698959927469","itemUrl": "https://www.facebook.com/marketplace/item/1976698959927469/","listingTitle": "iPhone 13 128GB - Unlocked","description": { "text": "Excellent condition, barely used, comes with original box and charger." },"condition": "Used - like new","listingCategoryId": "1428334323966278","listingAttributes": [{ "attribute_name": "condition", "label": "Used - like new", "value": "PC_USED_LIKE_NEW" },{ "attribute_name": "brand", "label": "Apple", "value": "apple" }],"listingPrice": { "formatted_amount_zeros_stripped": "$350", "amount": "350", "amount_with_offset_in_currency": "35000", "currency": "USD" },"strikethroughPrice": null,"location": { "latitude": 30.2672, "longitude": -97.7431 },"locationText": { "text": "Austin, TX" },"deliveryTypes": ["local_pick_up"],"listingPhotos": [{ "image": { "uri": "https://scontent.xx.fbcdn.net/photo1.jpg", "width": 960, "height": 720 }, "id": "111" }],"primaryListingPhoto": { "id": "111", "photo_image_url": "https://scontent.xx.fbcdn.net/photo1.jpg" },"listingVideo": [],"timestamp": "2026-06-30T14:12:05.000Z","isSold": false,"isPending": false,"isLive": true,"isHidden": false,"isViewerSeller": false,"customSubTitlesWithRenderingFlags": []}
Note: this is the deep-mode (default) shape. With deepScrape: false, the same listing is returned as a lighter, snake_case record instead (see the quick-mode field table above) — the two modes are not merged into one schema.
How does it work?
On each run, Facebook Marketplace Scraper requests an Apify residential proxy session and warms up a guest datr cookie against facebook.com, so its first real request looks like an ordinary browser visit instead of a cold IP. It then fetches the search page's HTML directly over HTTP — no browser is launched — and reads that page's live GraphQL document ID and session tokens (lsd, fb_dtsg) out of Facebook's own JavaScript bundles and inline page data, rather than relying on hardcoded values. That dynamic discovery is what lets it keep working through Facebook's routine token and endpoint rotation without needing a code update every time Facebook ships a frontend change. From there it pages through Marketplace's own search GraphQL endpoint using Facebook's cursor, and — in deep mode — fetches each listing's detail-page GraphQL query and merges the returned fragments into one record. Only data Facebook already serves to a logged-out visitor is ever returned, and the output schema stays stable regardless of Marketplace UI changes.
Integrations
Facebook Marketplace Scraper is a standard Apify Actor, so it works with anything that can call the Apify API — your own code, no-code automation tools, or AI agent frameworks.
Calling Facebook Marketplace Scraper programmatically
from apify_client import ApifyClientclient = ApifyClient("<APIFY_TOKEN>")run = client.actor("facebook-marketplace-scraper").call(run_input={"urls": ["https://www.facebook.com/marketplace/108479165840750/search/?query=phone"],"count": 20,"deepScrape": True,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item)
Works in Go, Ruby, Node.js, cURL — any language that can make an HTTP request.
MCP integration for AI agents
Facebook Marketplace Scraper is reachable through Apify's Actors MCP Server. Register it with apify mcp install claude-code --tools facebook-marketplace-scraper (swap claude-code for cursor, vscode, or another supported client), authenticated with your APIFY_TOKEN. This exposes the Actor as a callable tool to Claude Desktop, Claude Code, Cursor, VS Code (Copilot agent mode), and other MCP-compatible clients.
No-code tools (n8n, Make, LangChain)
In n8n, use the Apify node's "Run Actor and get dataset" operation pointed at facebook-marketplace-scraper. In Make, add the Apify app's "Run an Actor" module with the same Actor ID and map the output dataset into your scenario. In LangChain, use ApifyWrapper/ApifyDatasetLoader to run the Actor and load its dataset directly into a chain, agent, or vector store.
Is it legal to scrape Facebook Marketplace?
Scraping publicly available data — data any logged-out visitor can already see — is generally lawful, and Facebook Marketplace Scraper only returns what a public search or listing page already shows. Marketplace listings are business/product data (titles, prices, categories, descriptions), which falls under Facebook's terms of service and database-rights considerations rather than a personal-data regime. One exception worth noting: quick mode's marketplace_listing_seller field carries the seller's public name/profile link, which can identify an individual private seller — if you store that field in bulk, GDPR/CCPA-style personal-data obligations may apply to it specifically. Consult legal counsel if your use case involves bulk storage of personal data.
Frequently asked questions
What Facebook Marketplace listing fields does Facebook Marketplace Scraper return?
The top fields are listingTitle, listingPrice, locationText, condition, and listingPhotos in deep mode (the default) — see the full field tables above for both output modes.
Does Facebook Marketplace Scraper require a Facebook account or login?
No. It runs entirely logged-out, bootstrapping its own guest session (a datr cookie plus fresh lsd/fb_dtsg tokens) against Facebook's public pages on every run — you never provide a Facebook username, password, or cookie.
How many listings can I extract in one run?
As many as your urls and count inputs allow: each URL paginates through Marketplace's search results until it hits your per-URL count cap, or 0 for as many as Facebook's feed returns before it stops paginating.
What happens if a listing is removed or sold?
A sold listing is still returned with isSold/is_sold set to true rather than being silently dropped, so you can filter on that flag. A listing that no longer resolves at all (deleted or fully inaccessible) simply isn't collected — the Actor never fabricates a placeholder row for it.
Can I scrape multiple Facebook Marketplace URLs at once?
Yes. urls accepts an array, so one run can process many search URLs — different queries, cities, or categories — in parallel, each paginated independently.
Does Facebook Marketplace Scraper work with Claude, ChatGPT, and other AI agent tools?
Yes. It's registered with Apify's Actors MCP Server (see Integrations above) for MCP-native clients like Claude Desktop and Claude Code, and it's callable as a plain HTTP/API endpoint by any other agent framework.
How does Facebook Marketplace Scraper compare to other Facebook Marketplace scrapers?
As observed on the Apify Store on 2026-07-25: Apify's own apify/facebook-marketplace-scraper prices deep-scrape access ("includeListingDetails") from $2.60 per 1,000 listings; happitap/facebook-marketplace-listings-scraper advertises "fast and deep scrape modes" from roughly $1.00 per 1,000 results. Facebook Marketplace Scraper returns a comparable core field set (title, price, location, photos, seller) in quick mode and a comparably detailed record (structured listingAttributes, condition, coordinates, full photo set) in deep mode, billed simply per dataset row (row_result).
Does Facebook Marketplace Scraper return data in a format LLMs can use directly?
Yes. Output is typed, normalized JSON with consistent field names across runs — no HTML parsing or CSS selectors involved. Pass it directly to an LLM prompt, index it into a vector store, or feed it to an agent tool.
What happens when Facebook changes its layout or anti-bot system?
The Actor re-discovers its GraphQL document ID and session tokens from Facebook's live HTML/JS on every run rather than hardcoding them, so it's built to keep working through routine Facebook changes, and the output schema stays stable. No specific turnaround time is promised for deeper structural changes.
Can I use Facebook Marketplace Scraper without managing proxies or browser infrastructure?
Yes. It handles Apify residential proxy allocation, session rotation, and guest-cookie warmup automatically. There's no browser to manage either — it talks to Facebook's own GraphQL and HTML endpoints directly over HTTP rather than driving a rendered browser.
Which Facebook Marketplace listing fields work best for AI training data and RAG indexing?
For RAG, index description.text, listingTitle, and listingAttributes — the high-information text fields. For training or scoring pipelines, listingPrice, condition, and timestamp return as consistently typed primitives across every listing.
Related scrapers
| Scraper Name | What it extracts |
|---|---|
| Facebook Posts Scraper | Public Facebook Page timeline posts, captions, reactions, and media |
| Facebook Page Posts Scraper With Engagement Analytics | Page posts plus derived engagement metrics (virality, rank, best posting hour) |
| Facebook Groups Scraper With Lead & Contact Finder | Public group posts mined for emails, phone numbers, and business-intent signals |
| Facebook User Search Scraper: Photos & AI Bio Analysis | Public profile search results with photo galleries and optional AI bio analysis |
| Facebook Ads Library Scraper & Creative Media | Meta Ad Library creatives — images, video, ad copy, and format analytics |
| 🔥 Facebook URL → ID Scraper | Resolves any public Facebook URL, username, or handle into a stable Facebook ID |
Your feedback
Found a bug or a field that doesn't match what Facebook actually returns? Let us know via the Issues tab on this Actor's Apify Console page so it can be checked and fixed. Feedback like this is what keeps the field list and extraction logic accurate as Facebook changes its site.
