Facebook Marketplace
GET /v1/facebook/marketplace-search

Facebook Marketplace Search API

Search Marketplace by keyword + city — filters, isLocal/shipsOutsideRadius, opaque cursor (2 credits).

2 credits per request
TL;DR
Search Marketplace by keyword + city — filters, isLocal/shipsOutsideRadius, opaque cursor (2 credits). The Facebook Marketplace Search API (Facebook Marketplace) is a single authenticated GET request to /v1/facebook/marketplace-search that responds with clean JSON and costs 2 credits. Pass cache=true for a free 24h cache hit; default is always fresh. Start with 100 free credits — no credit card.

What is the Facebook Marketplace Search API?

Search Facebook Marketplace with a product keyword and a required search-origin city (searchLocation, or the location alias — no backend default city, no lat/lng required). Major US metros resolve to Facebook's numeric city-page id (verified hub scoping); other cities resolve to a vanity slug. The origin is echoed as searchLocation on the envelope and inside filters — listings[].location is a different object (where the item is). Each result: title, price + priceAmount (minor units), categoryId, location{name,city,state,countryCode,latitude,longitude}, deliveryTypes, status (available|pending|sold) with isSold/isPending/isHidden, cover image, createdAt, mediaUrlsExpireAt from Meta CDN oe= (~4.4 days), plus isLocal and shipsOutsideRadius so nationwide shipped listings (SHIPPING / SHIPPING_ONSITE) are not mistaken for nearby pickups. Facebook can surface shipped inventory outside radiusMiles and can broaden the keyword (a Rawlings search may include other brands — that is Facebook, not our matcher; sortBy=creation_time is recency, not relevance). daysSinceListed is Facebook's calendar-day window (1 = since the start of yesterday, not a rolling 24 hours). Optional filters: minPrice, maxPrice, sortBy, daysSinceListed, condition, deliveryMethod, availability, radiusMiles, category. hasMore is true only when nextCursor is present (same rule as tiktok/trending-feed and truth-social/user-posts; nextCursor is always keyed, null when exhausted). Default list path is flat 2 credits (cover photo in image — photos[] only when the card has more than one). Pass details=true for description, condition, coordinates, full photo gallery, seller{} when Facebook exposes it, and distanceMiles — billed as 2 + 2 credits per listing. timings{path,fetchMs,parseMs,resolveMs,totalMs} is the catalogue template — no root fetchMs/totalMs twins. cached is always keyed (true on cache=true hit or labelled last-good; default cache=false so identical live calls each bill). First-paint is typically ~28s after a cold Decodo hop (~50s); read timings.fetchMs. The origin dies at 90s — a live miss with a 6h last-good page is labelled stale at 0 credits. A miss with no snapshot is 504 UPSTREAM_TIMEOUT (0 credits) with timings.

What you get

  • Required searchLocation (echoed in filters; location alias still works)
  • isLocal / shipsOutsideRadius on every row
  • mediaUrlsExpireAt from CDN oe= + timings nest + cached
  • details=true = 2 + 2 credits per listing (stated upfront)

Try it

Open in Playground

Fill in the parameters below and copy a ready-to-run request, or open the live Playground to run it against your account (no API key paste).

Parameters

Sign in to run live
curl "https://api.captapi.com/v1/facebook/marketplace-search?q=desk%20chair&searchLocation=Austin%2C%20TX" \
  -H "Authorization: Bearer capt_live_..."
# or: -H "x-api-key: capt_live_..."

Edit the parameters and the code updates instantly. Switch languages and hit copy.

Example response

{
  "success": true,
  "data": {
    "query": "desk chair",
    "searchLocation": "Austin, TX",
    "filters": {
      "minPrice": "50",
      "maxPrice": "200",
      "sortBy": "price_ascend",
      "daysSinceListed": "30",
      "searchLocation": "Austin, TX"
    },
    "totalReturned": 2,
    "hasMore": true,
    "cached": false,
    "nextCursor": "eyJ2IjoxLCJxIjoiZGVzayBjaGFpciIsImxvYyI6IkF1c3RpbiwgVFgiLCJmIjp7Im1pblByaWNlIjoiNTAiLCJtYXhQcmljZSI6IjIwMCIsInNvcnRCeSI6InByaWNlX2FzY2VuZCIsImRheXNTaW5jZUxpc3RlZCI6IjMwIn0sInNraXAiOjUsImVjIjoie1wicGdcIjowLFwiYjJjXCI6e1wiYnJcIjpcIlwiLFwiaXRcIjowLFwiaG1zclwiOmZhbHNlLFwidGJpXCI6MH0sXCJjMmNcIjp7XCJiclwiOlwiQWJwaXVWdElpSVhFajlWV0ZVZEl4czFJUi13SldycGx1NWlNTGNYOURiMTBTQzhFQk93YzFXZi1RcmpOcDM3elBFWlg5ZGJNdlNDa0ZUay1sclBucTlCTnJGWURUdHg5bFZlMFhGd2FGdEQ0RG03T3RkemJBMU5MVWdkLUFrclRhc3hPZHVmWldmVkJTZlJTTG1SYmZydWVBVW85QTRNZXBqc1I0cm0zV09FejNSYlhIVnRrcm9SV21JZ1liUUZYN0Y0WnpfNnlhQTRkdThSY1BRbzJJeUwtcC1Ca3hlTVhHblFLSHZ1ZXJyZ2J2alN0M2hXNEFNdDZlclE1UkpGOUhSdFk3b1RLbGI2bTVfTUZEd2FqcXdMbUJhSzBKWlVKN3ZsUnczVFlQMm9SSjVoMDFxSndUU2Z6enduMkFodEFlcVFaUEs0eWV5OEc0WGZ0bm81cERJYzZDUWNzTWtRdEJjZDE2R3FNanQwQXhybkNJM1A0OFZINmZqcG9vM3hGTnJqU3ZvRDhOOGNxbVFMaVJzVy1SRlF2am9CNTdGWkkzVkpMLXhLN204cUVNaUczcnZKUlRJd2ZLS2VHdTlBckJXbi1SODJuNkVPUU9MU2loUkppTlY4Q0Rxamw0WnIyUVJmcXFMN3hmNzZPSnBzaEVxWi05Z1JWRWlzaFdJcUx1eWY0YzF6NE1zMUZ5YTNDeUZxamgtdDBtei1nR3dTZGhEOEhxelloQXhYWGZsU0NkdGUxVWIwaVBiRVctSUhqQmVjXCIsXCJpdFwiOjI0LFwicnBi …",
    "listings": [
      {
        "platform": "facebook",
        "id": "4482233215369733",
        "title": "Vintage 1980s Postmodern \"American Lighting\" Gooseneck Desk Lamp",
        "url": "https://www.facebook.com/marketplace/item/4482233215369733/",
        "price": 50,
        "priceFormatted": "$50",
        "priceAmount": 5000,
        "currency": "USD",
        "categoryId": "1569171756675761",
        "location": {
          "name": "Benson, AZ",
          "city": "Benson",
          "state": "AZ",
          "countryCode": "US",
          "latitude": null,
          "longitude": null
        },
        "cityPageId": "109791499039942",
        "isSold": false,
        "isPending": false,
        "isHidden": false,
        "deliveryTypes": [
          "IN_PERSON",
          "SHIPPING_ONSITE"
        ],
        "image": "https://scontent-atl3-3.xx.fbcdn.net/v/t39.84726-6/748718464_1472100928021023_7004614235492134530_n.jpg?stp=c0.87.526.526a_dst-jpg_p526x395_tt6&_nc_cat=109&ccb=1-7&_nc_sid=92e707&_nc_ohc=Osco_iBPSHsQ7kNvwE88Z2B&_nc_oc=AdrnNrq4GxtoKGWCDi_qxKj2BfO-OcysnTpk7mDO5d-84zPauj6YWLhxJPZuiRErURoSW7OUci-LjqdvjivdYc4u&_nc_zt=14&_nc_ht=scontent-atl3-3.xx&_nc_gid=48UkL5OoevcKmJAZmxtYnw&_nc_ss=7b289&oh=00_AQFTCh3FFtSTB-AA28V6Jr1NtrTs9PSVie1b1KW_xUkkNw&oe=6A753B85",
        "createdAt": "2026-07-16T06:02:16+00:00",
        "status": "available",
        "isPublished": true,
        "isLocal": false,
        "shipsOutsideRadius": true
      },
      {
        "platform": "facebook",
        "id": "2467979733629080",
        "title": "Gaiam Classic Balance Ball Chair - Ergonomic Office/Desk Chair",
        "url": "https://www.facebook.com/marketplace/item/2467979733629080/",
        "price": 50,
        "priceFormatted": "$50",
        "priceAmount": 5000,
        "currency": "USD",
        "categoryId": "1383948661922113",
        "location": {
          "name": "Fresno, CA",
          "city": "Fresno",
          "state": "CA",
          "countryCode": "US",
          "latitude": null,
          "longitude": null
        },
        "cityPageId": "107983435897193",
        "isSold": false,
        "isPending": false,
        "isHidden": false,
        "deliveryTypes": [
          "IN_PERSON",
          "SHIPPING_ONSITE"
        ],
        "image": "https://scontent-atl3-3.xx.fbcdn.net/v/t39.84726-6/749286700_1116782047845292_1788708914246608626_n.jpg?stp=c0.81.526.526a_dst-jpg_p526x395_tt6&_nc_cat=110&ccb=1-7&_nc_sid=92e707&_nc_ohc=gbzkYGqnXmYQ7kNvwGzH1qf&_nc_oc=AdqLUHLAdzpxyU4TF9F6Xf5v9Tib9M6UCrmYThgY8kMR7j8y-uMyvFm3zwMzYYMwX1rcrfF1-yMiBdhJbknk-W2-&_nc_zt=14&_nc_ht=scontent-atl3-3.xx&_nc_gid=48UkL5OoevcKmJAZmxtYnw&_nc_ss=7b289&oh=00_AQHJWOlgp25sCHb9Xzuo5yQVzSCjOZpSF6EaQpKDCudKZA&oe=6A751DFD",
        "createdAt": "2026-07-18T17:45:28+00:00",
        "status": "available",
        "isPublished": true,
        "isLocal": false,
        "shipsOutsideRadius": true
      }
    ]
  }
}

Billing metadata is returned in response headers: X-Captapi-Credits (credits charged), X-Captapi-Cache (hit or miss), and X-Captapi-Source. Failed requests (4xx/5xx) are never charged. See the full list of error codes in the error reference.

Response structure

A successful call returns success and a data object with the following fields:

Top-level fields

  • queryThe search query you sent.
  • searchLocationSearch-origin city you sent (or the location alias). Always echoed here and inside filters — not a silent default. Distinct from listings[].location.
  • totalReturnedNumber of items returned in this response.
  • hasMoreTrue only when nextCursor is present. Same catalogue rule as tiktok/trending-feed and truth-social/user-posts (those two may set hasMore true with a null cursor only when truncatedReason=single_page_only).
  • cachedAlways keyed. true on a cache=true hit or labelled last-good. Default cache=false — identical live calls each bill 2 credits.
  • nextCursorAlways keyed. Opaque skip token within the fetched SSR page, or null when exhausted. Pass as cursor.

Filters

The filters object contains:

  • minPriceMin price. Example: "50".
  • maxPriceMax price. Example: "200".
  • sortBySort by. Example: "price_ascend".
  • daysSinceListedDays since listed. Example: "30".
  • searchLocationSearch-origin city you sent (or the location alias). Always echoed here and inside filters — not a silent default. Distinct from listings[].location.

Listings

Each item in listings contains:

  • platformPlatform identifier for this response (matches the endpoint's platform).
  • idId of this listings item.
  • titleTitle of this listings item.
  • urlCanonical URL of the item.
  • pricePrice of the item.
  • priceFormattedFormatted price string.
  • priceAmountPrice in minor units (cents) for exact arithmetic — prefer over float price.
  • currencyCurrency code.
  • categoryIdCategory id when the platform exposes one.
  • locationRemoved from the envelope root (collided with listings[].location). Read searchLocation. Each listing.location is {name,city,state,countryCode,latitude,longitude}.
  • cityPageIdCity page id. Example: "109791499039942".
  • isSoldConvenience bool for status === sold.
  • isPendingConvenience bool for status === pending.
  • isHiddenIs hidden. Example: false.
  • deliveryTypesFacebook delivery enums (e.g. IN_PERSON, SHIPPING_ONSITE).
  • imageCover photo URL. Signed Meta CDN — check mediaUrlsExpireAt (~4.4 days from oe=).
  • createdAtCreation date (ISO 8601).
  • statusListing availability: "available" | "pending" | "sold". Prefer this over isPublished.
  • isPublishedWhether Facebook still publishes the listing page (their is_live). Not a livestream. Omitted when status is sold/pending — prefer status.
  • isLocaltrue when the listing's city/state matches the search origin (or distanceMiles ≤ radiusMiles when coords exist).
  • shipsOutsideRadiustrue when the listing offers shipping and isLocal is false — typical nationwide SHIPPING_ONSITE inventory.

Timings

The timings object contains:

  • pathPath. Example: "search".
  • fetchMsFetch ms. Example: 28105.
  • parseMsParse ms. Example: 1.
  • resolveMsResolve ms. Example: 0.
  • totalMsTotal ms. Example: 28107.

Parameters

NameTypeRequiredDescription
qstringYesProduct or keyword to search Facebook Marketplace for.
searchLocationstringYesSearch-origin city or place name, e.g. 'Austin, TX'. Required — there is no default city. Echoed on the envelope and inside filters. Not listings[].location.
locationstringNoAlias of searchLocation. Prefer searchLocation. Either one is required.
limitnumberNoHow many listings to return (1–200). Flat 2 credits when details=false; details=true billed as 2 + 2 per listing.
minPricenumberNoMinimum price in local currency units.
maxPricenumberNoMaximum price in local currency units.
sortBystringNosuggested | distance | creation_time | price_ascend | price_descend.
daysSinceListedstringNoFacebook calendar-day recency: 1 = since the start of yesterday (not a rolling 24 hours), 7, or 30.
conditionstringNonew, like_new, good, fair (comma-separated ok).
deliveryMethodstringNolocal_pickup | shipping | all. Shipped listings can appear nationwide outside radiusMiles — use local_pickup for nearby-only; rows expose isLocal / shipsOutsideRadius.
availabilitystringNoavailable | sold | all.
radiusMilesnumberNoRadius in miles: 1,2,5,10,20,40,60,80,100,250,500. Does not exclude nationwide shipped inventory.
categorystringNoTop-level category slug, e.g. electronics.
cursorstringNoOpaque pagination cursor from a previous nextCursor.
detailsbooleanNoWhen true, adds description/condition/coordinates/full photo gallery/seller/distanceMiles — billed as 2 + 2 credits per listing. Default false → flat 2 credits; cover photo is still in image.
cachebooleanNoSet true to serve from the 24h response cache (0 credits on hit). Default false — always fetch fresh.

Authentication: send your key as Authorization: Bearer capt_live_.... A typical call costs 2 credits. Pass cache=true for a free 24h cache hit; default is always fresh.

Using an AI agent? This endpoint is the MCP tool facebook_marketplace_search via @captapi/mcp. Set it up →

How it works

  1. 1. Sign up — get 100 free credits, no card required.
  2. 2. Create a key from your dashboard.
  3. 3. Send one request to /v1/facebook/marketplace-search and parse the JSON response.

Use cases

Local inventory

Search by city name + keyword; filter isLocal or deliveryMethod=local_pickup to drop nationwide shipped rows.

Price band monitoring

minPrice/maxPrice + sortBy=price_ascend for deal alerts without scraping the UI.

Tiered detail fetch

List at flat 2 credits; pass details=true only when you need description/coords/gallery (2 + 2 per listing).

Status filtering

Read status (available|pending|sold) — Facebook may keep sold listings published.

Frequently asked questions

What does the Facebook Marketplace Search API do?+

The Facebook Marketplace Search API lets you search and return matching results from a public Facebook Marketplace query using one GET request to /v1/facebook/marketplace-search. It returns clean JSON — no OAuth or infrastructure setup required.

How many credits does the Facebook Marketplace Search API cost?+

Each successful call costs 2 credits. Pass cache=true to serve from the 24h cache (0 credits on hit); default is always fresh. Selected profile endpoints also accept cacheMaxAge=1d|3d|7d|14d|30d. Failed or empty results are never charged.

Do I need a Facebook Marketplace API key or OAuth?+

No. A single Captapi key works across every platform Captapi supports — YouTube, TikTok, Instagram, Facebook, Twitter/X, Reddit, Threads, Bluesky, Pinterest, LinkedIn, Rumble, Spotify, Kwai, and more. We handle proxies, rate limits, retries, and authentication for you.

Why did I get a 504 after 100 or 210 seconds?+

Decodo headless is 55s scrape + 20s body drain (~75s on an empty miss). A second scroll hop after a live first-paint used to hang until the 90s wall and throw away the cards we already had. Search is first-paint only now. A 6h last-good page for the same query+city (any limit) is a labelled stale 200 at 0 credits; otherwise 504 UPSTREAM_TIMEOUT at 0 credits with timings.

Why is searchLocation Frisco, TX when I did not set a city?+

The backend has no default city — Marketplace search is geographic and requires searchLocation (or the location alias). Playground examples use Austin, TX. The origin is echoed as searchLocation on the envelope and inside filters so it is visibly an input, not a fact about each listing. listings[].location is where the item is.

Does daysSinceListed=1 mean the last 24 hours?+

No. That is Facebook's own calendar-day filter: 1 means listed on or after the start of yesterday, so a row can be up to ~39 hours old at the UTC day boundary. We pass it through — we do not re-window it to rolling 24 hours.

Why did a brand keyword return other products?+

Facebook broadens Marketplace search. sortBy=creation_time_descend is recency, not relevance. Pass-through — not our matcher.

Why is hasMore false with no nextCursor?+

nextCursor is always keyed (null when exhausted). hasMore is true only when nextCursor is present. Same catalogue rule as tiktok/trending-feed and truth-social/user-posts — those two may set hasMore true with a null cursor only when truncatedReason is single_page_only (more exist, unreachable). Marketplace first-paint leftover cards get a real skip cursor; a short filtered page is hasMore false, nextCursor null.

Why did three identical calls each cost 2 credits, and why was the first ~53s?+

cache defaults to false, so each live call bills. cached is always keyed — false on those live hops, true on a cache=true hit or labelled last-good. The 53s first call vs ~28s later is Decodo cold-path variance; timings.fetchMs is the upstream hop (parse/resolve stay ~0–1 ms).

Is the Facebook Marketplace Search API suitable for production use?+

Yes. It is a stable REST endpoint with predictable JSON and automatic retries. Pass cache=true to serve from the 24h cache (0 credits on hit); default is always fresh. Selected profile endpoints also accept cacheMaxAge=1d|3d|7d|14d|30d. Use it for analytics, monitoring, and content automation.

More Facebook Marketplace APIs

Ready to use the Facebook Marketplace Search API?

Sign up, grab your key, and make your first call in 60 seconds.

Facebook Marketplace Search API | Captapi — Captapi