OfferUp Scraper: Local Listings, Prices, Sellers
Pricing
from $1.33 / 1,000 listings
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
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
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
- Type what you want in Keywords (
iphone,sectional couch), and optionally Categories (Cars & Trucks, or the id5.1). - Add one or more Places:
Houston, TX, a ZIP code such as77002, or coordinates such as29.7604, -95.3698. - Optionally set a Radius, a price range, conditions, a seller type or the vehicle filters.
- Turn on Add listing details if you need descriptions, posted times, sellers and car fields.
- 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.
| Field | What it holds | Filled |
|---|---|---|
listingId, url, title, imageUrl, locationName, city, state, isLocalPickup | the listing as OfferUp's search shows it (state as a two letter code, also where OfferUp writes the state's name) | 100% |
price, priceText, isCallForPrice | price in USD as a number; null when the seller asks to call for the price | price on 99.6% |
sellerType | dealer (a vehicle dealer) or private (every other seller: private people and shops), OfferUp's own mark on every search row | 100% |
vehicleMiles | mileage shown on vehicle rows | the vehicle rows |
isPromoted | a promoted listing OfferUp placed at the top of the first pages | 4.3% of rows are promoted |
titleMatchesKeyword | every word of the keyword starts a word of the title | on keyword searches |
searchKeyword, searchCategory, searchLocation, searchLatitude, searchLongitude, searchRadiusMiles, searchSort, page, position | the search that found the listing, with the radius OfferUp applied | 100% |
description | the description (details) | 82% |
postedAt, lastEditedAt | when it was posted and last edited, UTC (details) | 100%, last edit 13% |
originalPrice, condition, conditionCode, isFirmPrice, quantity, listingState | details | 100% |
latitude, longitude, coordinatesRounded | the listing's map point (details); rounded to about 1 km for private sellers by default | 100% |
categoryId, categoryName, categoryPath, photoUrls, photoCount | details | 100% |
sellerId, sellerJoinedAt, sellerItemsSold | details | 100% |
sellerRatingAverage, sellerRatingCount | details | rated sellers 47% |
sellerName | dealers and business accounts; private sellers only with Include private sellers' personal data | dealers 100% |
sellerPhone | the 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 none | dealers 6 of 6, business accounts 5 of 7, private sellers 0 of 13 (2026-10-14) |
sellerIsAutosDealer, sellerIsBusiness, sellerIsTruyouVerified | details: 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, vehicleDrivetrain | vehicles (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:
| Event | Free plan | Bronze | Silver | Gold |
|---|---|---|---|---|
| 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
| Field | What it does |
|---|---|
keywords | Search words as you would type them on OfferUp (iphone, toyota camry). |
locations | US 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. |
categories | OfferUp categories by id (5.1), name (Cars & Trucks) or path (Vehicles > Cars & Trucks), from OfferUp's own list of 1,244. |
listingUrls | OfferUp listing links or listing ids; each is read with its details. |
radiusMiles | Distance 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. |
sort | newest (default), best_match, closest, price_low, price_high. A monitor and a search with places only read newest. |
minPrice, maxPrice | Price range in whole dollars, up to 1,000,000. Listings without a price are left out when it is set. |
conditions | NEW, OPEN_BOX, REFURBISHED, USED, BROKEN, OTHER (needs a keyword or category). |
sellerType | any, 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, vehicleMaxMileage | Cars & Trucks only (category 5.1 and its sub categories). OfferUp offers mileage limits of 25,000 to 200,000 in steps of 25,000. |
includePromoted | Include OfferUp's promoted listings (default on; each is marked isPromoted). |
onlyTitleMatches | Leave out related listings whose title does not carry the keyword (free). |
includeDetails | Read each delivered listing's details (Listing detail). |
includePrivateSellerDetails | Include 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). |
maxItems | Most listing rows this run delivers (default 100). |
maxPagesPerSearch | Results pages per search, 1 to 100 (default 10). |
monitorName | A 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.
Is it legal to scrape 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 ApifyClientclient = 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.