OfferUp Scraper: Local Listings, Prices, Sellers avatar

OfferUp Scraper: Local Listings, Prices, Sellers

Pricing

from $1.33 / 1,000 listings

Go to Apify Store
OfferUp Scraper: Local Listings, Prices, Sellers

OfferUp Scraper: Local Listings, Prices, Sellers

Scrape OfferUp listings by keyword, category and US city, ZIP code or map point with radius: title, price, place, photo and private or dealer seller. Optional details: description, posted time, condition, seller stats, car make, model, year and VIN. New listing monitor. JSON, CSV, Excel.

Pricing

from $1.33 / 1,000 listings

Rating

0.0

(0)

Developer

Automation Craft

Automation Craft

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

OfferUp Scraper: Local Listings, Prices, Sellers

Scrape OfferUp listings by keyword, category and US place into clean rows: title, price as a number, city and state, photo, link, seller type (private or dealer) and, for vehicles, the mileage. Search around a city ("Houston, TX"), a ZIP code or a map point with OfferUp's own radius, in several places at once. On request each listing's details are added: description, posted time, original price, condition, coordinates, category, all photos, the seller's join date, items sold, rating and the phone number OfferUp shows for dealers and business accounts, and for cars the make, model, year, mileage, color and VIN. Give the run a monitor name and schedule it: each run then delivers only the listings that are new.

No OfferUp account, no cookies, no API key, no browser. The Actor reads only what OfferUp shows every visitor, checks that OfferUp applied each search exactly as you sent it. Private sellers' name and phone number fields and exact coordinates are switched off by default, and contacts they write into texts are masked on a best effort basis.

This Actor is not affiliated with, endorsed or sponsored by OfferUp Inc. OfferUp is a trademark of OfferUp Inc.

Who uses it

  • Flippers and resellers: a monitor on a narrow search (a model, a price range, a few cities) that delivers each new listing once, newest first, to a spreadsheet, Slack or e-mail through Apify's integrations.
  • Car buyers and small dealers: Cars & Trucks around a city with year and mileage filters, dealers only or no dealers, with make, model, year, mileage and VIN from the details.
  • Price research: what a product sells for in several US cities, with prices as numbers and the original price next to the asking price.
  • Data teams and agents: a structured OfferUp feed through the Apify API, one schema for every category.

Quick start

  1. Type what you want in Keywords (iphone, sectional couch), and optionally Categories (Cars & Trucks, or the id 5.1).
  2. Add one or more Places: Houston, TX, a ZIP code such as 77002, or coordinates such as 29.7604, -95.3698.
  3. Optionally set a Radius, a price range, conditions, a seller type or the vehicle filters.
  4. Turn on Add listing details if you need descriptions, posted times, sellers and car fields.
  5. Run it, then download the dataset as Excel, CSV or JSON, or read it through the Apify API.

How new is new?

OfferUp shows a new listing to the public, and so to this Actor, about 30 minutes after it is posted: the newest public listings in Houston, Los Angeles, New York and Chicago were 30.0 to 31.2 minutes old (24 of 24, measured 2026-10-11). OfferUp sells the earlier view to its Premium members. This Actor reads the same public feed as every visitor; it does not see listings sooner.

How deep does a search go?

Searches read OfferUp's recent first order by default, page after page along OfferUp's own cursor, about 50 listings a page (100 for a search with places only). A recent first walk of 40 pages in Houston met almost no repeats (1,992 different "iphone" listings in 1,998 rows, about two weeks back), so depth is set by Maximum pages per search (10 by default, up to 100). In OfferUp's best match order listings start to repeat after about 12 pages; the run counts the repeats and bills each listing once. In recent first order OfferUp's search also returns related listings (a case for "iphone"); every row says titleMatchesKeyword, and Only titles with the keyword leaves the others out for free.

What you get

One row per listing (type: "listing"). Measured fill rates (2026-10-11): search rows from 1,390 rows of 14 pages, details from 62 listings.

FieldWhat it holdsFilled
listingId, url, title, imageUrl, locationName, city, state, isLocalPickupthe listing as OfferUp's search shows it (state as a two letter code, also where OfferUp writes the state's name)100%
price, priceText, isCallForPriceprice in USD as a number; null when the seller asks to call for the priceprice on 99.6%
sellerTypedealer (a vehicle dealer) or private (every other seller: private people and shops), OfferUp's own mark on every search row100%
vehicleMilesmileage shown on vehicle rowsthe vehicle rows
isPromoteda promoted listing OfferUp placed at the top of the first pages4.3% of rows are promoted
titleMatchesKeywordevery word of the keyword starts a word of the titleon keyword searches
searchKeyword, searchCategory, searchLocation, searchLatitude, searchLongitude, searchRadiusMiles, searchSort, page, positionthe search that found the listing, with the radius OfferUp applied100%
descriptionthe description (details)82%
postedAt, lastEditedAtwhen it was posted and last edited, UTC (details)100%, last edit 13%
originalPrice, condition, conditionCode, isFirmPrice, quantity, listingStatedetails100%
latitude, longitude, coordinatesRoundedthe listing's map point (details); rounded to about 1 km for private sellers by default100%
categoryId, categoryName, categoryPath, photoUrls, photoCountdetails100%
sellerId, sellerJoinedAt, sellerItemsSolddetails100%
sellerRatingAverage, sellerRatingCountdetailsrated sellers 47%
sellerNamedealers and business accounts; private sellers only with Include private sellers' personal datadealers 100%
sellerPhonethe seller's phone number as OfferUp shows it to any visitor, written as OfferUp gives it (8664012666), details; dealers and business accounts always, private sellers only with Include private sellers' personal data; null when OfferUp shows nonedealers 6 of 6, business accounts 5 of 7, private sellers 0 of 13 (2026-10-14)
sellerIsAutosDealer, sellerIsBusiness, sellerIsTruyouVerifieddetails: dealer flag, business account, TruYou verified (null when OfferUp does not state it)dealer flag 62 of 62
vehicleMake, vehicleModel, vehicleYear, vehicleMileage, vehicleColor, vehicleVin, vehicleTitleStatus, vehicleBody, vehicleTransmission, vehicleFuelType, vehicleTrim, vehicleDrivetrainvehicles (details)make on 14 of 14 vehicles read, VIN on 11 of 14

Private sellers' personal data is off by default. Switch on Include private sellers' personal data to also get, for private sellers, the name, the phone number and the exact coordinates (with details), and the phone numbers and e-mail addresses they write into the texts of a row (title, description, place, category and vehicle fields), all as OfferUp shows them to any visitor. With it off, the name and phone number are empty, coordinates are rounded to about 1 km, and contacts in the texts are masked on a best effort basis (a contact written in an unusual way can stay; other personal details a seller writes, such as a name, are not masked; a text longer than 100,000 characters is cut there, far beyond any OfferUp description). Dealers' and business accounts' contact details are delivered either way. You are responsible for a lawful use of personal data, GDPR included.

A real row (a dealer car with details, shortened):

{
"type": "listing",
"listingId": "fa5a4baf-f86c-347d-a274-4e0fc649923a",
"url": "https://offerup.com/item/detail/fa5a4baf-f86c-347d-a274-4e0fc649923a",
"title": "2026 Porsche Macan",
"price": 83679,
"originalPrice": 92220,
"locationName": "Plano, TX",
"sellerType": "dealer",
"vehicleMiles": 3192,
"postedAt": "2026-06-18T03:54:34.281Z",
"condition": "Used",
"categoryPath": "Vehicles > Cars & Trucks",
"sellerName": "Porsche Plano",
"sellerPhone": "8664012666",
"sellerJoinedAt": "2025-07-30T22:38:44Z",
"vehicleMake": "Porsche",
"vehicleModel": "Macan",
"vehicleYear": 2026,
"vehicleVin": "WP1AG2A50TLB40637",
"searchLocation": "Dallas, TX",
"searchRadiusMiles": 80,
"detailsIncluded": true
}

Free rows, never charged: one coverage row per search (type: "search": pages read, listings seen and delivered, listings already delivered or known to the monitor, listings left out by filters, the radius, order and category OfferUp applied, complete, stoppedBy, and for a monitor newListingsMayLieBeyond), status rows (type: "status") for input that cannot be used, a place OfferUp does not know (with OfferUp's suggestions), a category name several categories share (with their ids), a listing that no longer exists, a search OfferUp did not apply as sent (with what it applied and the values it offers), and a run summary (type: "summary") at the end.

How much does it cost to scrape OfferUp?

Pay per event, with Apify's Store discounts by plan:

EventFree planBronzeSilverGold
Listing (one listing row)$0.00186$0.0017$0.00154$0.00133
Listing detail (the details of a delivered listing, only when details are read)$0.0018$0.0016$0.0014$0.0012
Results page (only in monitor runs: one results page read, about 50 listings)$0.00015$0.00015$0.00015$0.00015
Actor start (once per run)$0.007$0.007$0.007$0.007

Platinum and Diamond plans pay the Gold price. The Store pricing card shows these prices per 1,000 events: "$1.86 / 1,000" on the Listing row means one listing costs 0.186 cents.

Examples on the Free plan: 100 listings cost $0.007 + 100 x $0.00186 = $0.193. 1,000 listings cost $1.867. 1,000 listings with their details cost $0.007 + 1,000 x ($0.00186 + $0.0018) = $3.667. An hourly monitor of 5 searches that reads 1 page each and finds 10 new listings costs $0.007 + 5 x $0.00015 + 10 x $0.00186 = $0.02635 per run.

Free: listings left out by your filters, listings already delivered in the run, listings a monitor delivered before, listings that no longer exist, places OfferUp does not know, searches OfferUp did not apply as sent, invalid input, coverage rows, status rows and the summary. A listing link is always read with its details, so each one delivered is billed as Listing plus Listing detail.

Work that delivers nothing is bounded: a run may send 40 requests plus 2 per listing, 2 per listing detail and 2 per Results page delivered before it stops with a status row that says so. A filter that almost no listing passes, or a long list of listing links that no longer exist, ends there; narrow the search or split the list. A monitor's own results pages are paid as Results pages and never count against it.

Input

FieldWhat it does
keywordsSearch words as you would type them on OfferUp (iphone, toyota camry).
locationsUS places: Houston, TX (or Houston, Texas), a 5 digit ZIP code (77002), or coordinates (29.7604, -95.3698). Each is checked with OfferUp's own place search and geocoder. A city must be written as OfferUp writes it (St Louis, MO); a free row lists OfferUp's suggestions when it is not.
categoriesOfferUp categories by id (5.1), name (Cars & Trucks) or path (Vehicles > Cars & Trucks), from OfferUp's own list of 1,244.
listingUrlsOfferUp listing links or listing ids; each is read with its details.
radiusMilesDistance around each place. OfferUp offers 5, 10, 20, 30 (default) or 50 miles in most categories, and 25, 80 (default), 100, 200 or 5000 in Cars & Trucks. Another value is answered with a free row listing the offered values.
sortnewest (default), best_match, closest, price_low, price_high. A monitor and a search with places only read newest.
minPrice, maxPricePrice range in whole dollars, up to 1,000,000. Listings without a price are left out when it is set.
conditionsNEW, OPEN_BOX, REFURBISHED, USED, BROKEN, OTHER (needs a keyword or category).
sellerTypeany, private or dealer, from OfferUp's own mark on every search row: dealer keeps vehicle dealers, private every other seller (private people and shops such as furniture stores; with details, sellerIsBusiness tells them apart).
vehicleMinYear, vehicleMaxYear, vehicleMaxMileageCars & Trucks only (category 5.1 and its sub categories). OfferUp offers mileage limits of 25,000 to 200,000 in steps of 25,000.
includePromotedInclude OfferUp's promoted listings (default on; each is marked isPromoted).
onlyTitleMatchesLeave out related listings whose title does not carry the keyword (free).
includeDetailsRead each delivered listing's details (Listing detail).
includePrivateSellerDetailsInclude private sellers' personal data: names, phone numbers, exact coordinates, and the phone numbers and e-mail addresses written into the row's texts, which are otherwise masked on a best effort basis (off by default).
maxItemsMost listing rows this run delivers (default 100).
maxPagesPerSearchResults pages per search, 1 to 100 (default 10).
monitorNameA name for the monitor memory (new listings only).

Places, keywords and categories are combined: every keyword is searched in every category around every place (at most 100 searches a run). Example input:

{
"keywords": ["ps5", "nintendo switch"],
"locations": ["Houston, TX", "Dallas, TX", "78701"],
"maxPrice": 400,
"sellerType": "private",
"onlyTitleMatches": true,
"maxItems": 300
}

Cars from private sellers, 2018 or newer, under 75,000 miles, with details:

{
"categories": ["5.1"],
"keywords": ["honda civic"],
"locations": ["Phoenix, AZ"],
"vehicleMinYear": 2018,
"vehicleMaxMileage": 75000,
"sellerType": "private",
"includeDetails": true
}

The monitor: new listings only

Give the run a Monitor name and schedule it. The monitor remembers every listing it delivered: a later run with the same name and the same settings reads the newest Maximum pages per search pages of each search (its window) and delivers and bills only the listings it has not delivered before; listings it delivered before are skipped for free. A monitor run pays a Results page event for every page it reads, so keep the window small for a frequent monitor (1 or 2 pages an hour is enough for most searches). Listings a run did not reach (its limits, an error) are delivered by a later run while they are still in the window, and a listing your filters left out is judged again on every run. When the last page of the window still held new listings, the coverage row says newListingsMayLieBeyond: true: more listings arrived between two runs than the window holds, so raise the pages or run more often. A monitor name belongs to one set of settings; use a new name for other searches, and schedule runs on one name so they do not overlap (an overlapping run reads nothing and says why). A monitor remembers up to 100,000 delivered listings; after that it holds new ones back with a free status row: start a new monitor name.

FAQ

Does OfferUp have an API?

OfferUp offers no public API for its listings. This Actor reads the same public search and listing data any visitor sees and gives you the listings as rows that you can read through the Apify API, with no key from OfferUp.

This Actor reads only public data without logging in: what OfferUp shows any visitor, including the phone number it shows for dealers and business accounts. It never requests the e-mail addresses OfferUp holds. OfferUp's terms restrict automated collection and commercial use; you are responsible for a lawful use of the data you collect, including personal data.

How do I get notified when new OfferUp listings are posted?

Run a search with a Monitor name on an Apify schedule (every hour, for example). Each run delivers only the listings that are new to the monitor; connect the run to Slack, e-mail, Google Sheets or a webhook with Apify's integrations. New listings reach OfferUp's public feed about 30 minutes after they are posted.

Can I search OfferUp in another city or nationwide?

Yes for other cities: give any US city as "City, ST", a ZIP code or coordinates, several in one run, with OfferUp's radius of up to 50 miles (5,000 in Cars & Trucks). OfferUp is local pickup only, so there is no nationwide search; list the cities you want.

Will I get blocked when scraping OfferUp?

The Actor uses Apify's proxy and moves to a fresh address when OfferUp refuses one (at most three times per run). If OfferUp keeps refusing, the run stops with a status row that says so rather than delivering partial data as complete.

Why does this Actor run with limited permissions?

It needs no access to your other Apify data. It only writes to its own run's dataset and key-value store and, when you use a monitor, to one named key-value store it creates itself for that monitor.

What this Actor does not do

  • No listings sooner than the public feed: OfferUp shows a new listing about 30 minutes after it is posted (Premium members see it earlier).
  • No e-mail field: OfferUp's own e-mail field is never requested.
  • No nationwide search and no shipping filter: OfferUp has been local pickup only since October 2025.
  • No radius, price or condition that OfferUp does not offer: OfferUp would replace it without a word, so such a search is answered with a free row that lists the values OfferUp offers.
  • No pasted OfferUp search links: a search link does not carry its place (OfferUp keeps it in a cookie); give keywords, categories and places instead.
  • No price history, price drop alerts or tracking of sold and removed listings: the monitor delivers new listings only.
  • No deal score and no built in alerts: connect Apify's integrations (Slack, e-mail, a webhook) to a monitor run, and score the rows with your own rule.
  • No age filter ("posted in the last N hours"): a search row carries no post time (the details do); a monitor delivers only what is new since its last run.
  • No vehicle make filter: OfferUp's make filter takes internal codes; search the make as a keyword in Cars & Trucks.
  • No view counts, messages, offers, posting, or anything behind a login.
  • No photo download: photo addresses are in every row.

API

curl -X POST "https://api.apify.com/v2/acts/automation_craft~offerup-scraper/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"keywords": ["iphone"], "locations": ["Houston, TX"], "maxItems": 20}'
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });
const run = await client.actor('automation_craft/offerup-scraper').call({ keywords: ['iphone'], locations: ['Houston, TX'], maxItems: 20 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((x) => x.type === 'listing'));
from apify_client import ApifyClient
client = ApifyClient("YOUR_API_TOKEN")
run = client.actor("automation_craft/offerup-scraper").call(run_input={"keywords": ["iphone"], "locations": ["Houston, TX"], "maxItems": 20})
rows = [x for x in client.dataset(run["defaultDatasetId"]).iterate_items() if x["type"] == "listing"]

Changelog

See the Changelog tab.

More data tools by Automation Craft