# OfferUp Scraper — Local Listings, Prices & Details, No Phones (`highbrow_fame/offerup-listings`) Actor

OfferUp listings around any US city or ZIP: price, condition, category, town and state, post date, firm price, photos, car make, model and mileage. Links or keywords. No phones, no seller names.

- **URL**: https://apify.com/highbrow_fame/offerup-listings.md
- **Developed by:** [yestrue](https://apify.com/highbrow_fame) (community)
- **Categories:** E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.50 / 1,000 listing delivereds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## OfferUp Scraper — Local Listings, Prices & Details, No Phones

Get listings from OfferUp, the US local marketplace: title, price, condition, category, town and state, when it was posted, whether the price is firm, the photo and the full description — and for cars the make, model, year, trim and mileage. Paste your OfferUp search links, or type keywords and a US city or ZIP code.

**Why this one**

- 🔗 **Your search, as you set it up.** Paste an OfferUp search, category or city link (…/search?q=sofa, …/c/cars-and-trucks/in/dallas-tx). Or type keywords and places — 98101, "Austin, TX" — and choose distance, category, price, condition and sort below.
- ⚡ **Fast.** A live test run read three searches with all details — cars at $5,000–15,000 around Dallas, sofas up to $300 within 20 miles of downtown Chicago, new or open-box iPhone 15s at $200–700 around Phoenix — 939 listings in 25 seconds.
- 📋 **Details included, at no extra charge.** Description, condition, category, post date, firm price and car data come with every listing — 50 listings in one extra request. Untick **Include listing details** for the search data only: a live run read 2,000 bikes around Los Angeles that way in 60 seconds.
- 🔒 **No phone numbers, no seller names.** Private sellers — nearly everyone on OfferUp — are described by town and state only: no name, no profile, no rating, no map point. Car dealers keep their business name. Phone numbers and e-mail addresses in titles and descriptions are replaced with `[phone removed]` / `[e-mail removed]`, and a street address in a private seller's description with `[address removed]`.
- 💸 **You pay only for listings delivered.** A link that is not an OfferUp search, or a place OfferUp does not know, comes back as a free record with the reason.

### What you get

For every listing:

| Field | What it is |
|---|---|
| `listingId`, `url`, `title` | the listing |
| `price`, `originalPrice`, `currency`, `isFirmPrice`, `callForPrice` | the asking price in USD; `originalPrice` when the seller has lowered it |
| `condition` | New, Open box, Reconditioned, Used, For parts, Other |
| `category`, `categoryPath` | e.g. "Bikes & Cycling" and "Sports & Outdoors > Bikes & Cycling" |
| `description` | the seller's text |
| `location`, `city`, `state` | the town and state of the listing — never a street or a map point |
| `postedAt`, `editedAt` | when it was posted and last edited |
| `localPickup`, `shippingAvailable`, `shippingPrice` | how the item changes hands |
| `sellerType`, `sellerName` | private or dealer; the business name for car dealers only |
| `isPromoted` | a paid placement in the results (it still matches your search) |
| `image`, `imageCount` | the first photo in full size, and how many there are |
| `mileage`, `make`, `model`, `year`, `trim`, `titleStatus`, `color`, `fuel`, `body`, `transmission` | for cars and motorcycles, as far as the seller filled them in |
| `input`, `searchLocation`, `position`, `scrapedAt`, `status`, `error` | which search it came from, and why a search gave nothing |

Without details a listing keeps its title, price, town, seller type, mileage, one photo and the link; the fields only the listing page has are empty.

#### Example

A real record from a live run — cars and trucks around Dallas at $5,000–15,000, newest first, 25 September 2026:

```json
{
  "input": "https://offerup.com/c/cars-and-trucks/in/dallas-tx?SORT=-posted&PRICE_MIN=5000&PRICE_MAX=15000",
  "searchLocation": "Dallas, TX",
  "position": 7,
  "listingId": "1e044ed1-c713-3c79-b3bd-6396e0fb5782",
  "url": "https://offerup.com/item/detail/1e044ed1-c713-3c79-b3bd-6396e0fb5782",
  "title": "2008 Jeep Wrangler",
  "price": 9995,
  "currency": "USD",
  "isFirmPrice": false,
  "condition": "Used",
  "category": "Cars & Trucks",
  "categoryPath": "Vehicles > Cars & Trucks",
  "description": "YES, WE ARE OPEN!!\n\nCall or Message Us Today!\n \nLocated in LAKE WORTH, DFW AUTO LEADER is a pre-owned, late model dealer that provides customers with a complete automotive experience…",
  "location": "Lake Worth, TX",
  "city": "Lake Worth",
  "state": "TX",
  "postedAt": "2026-09-25T08:24:46.208Z",
  "localPickup": true,
  "shippingAvailable": false,
  "sellerType": "dealer",
  "sellerName": "DFW Auto Leader",
  "isPromoted": false,
  "image": "https://images.offerup.com/WmpvkCtq6u45hqJM06kbKm0_SKI=/823x652/6c4a/6c4a4662008b47a3b968a59e7672cbb5.jpg",
  "imageCount": 30,
  "mileage": 174633,
  "make": "Jeep",
  "model": "Wrangler",
  "year": 2008,
  "trim": "Unlimited X",
  "color": "blue",
  "fuel": "Regular gasoline",
  "body": "Sport Utility",
  "status": "OK"
}
```

A private seller's listing looks the same, with `"sellerType": "private"` and `"sellerName": null`.

### How to use it

1. Paste **Search links** from offerup.com, one per line — or type **Keywords** and **Locations** (a US ZIP code or "City, ST") and choose the filters.
2. OfferUp keeps the place you searched around in your browser, not in the link: a link without a city or ZIP code in it is searched around each place under **Locations**.
3. Set **Max listings per search**, press **Start**, and download the results from the **Output** tab as JSON, CSV or Excel.

To follow new listings, choose **Newest first**, save your input as a task and schedule it daily.

You can also call it from the Apify API, from Make, Zapier or n8n, or from an AI agent through the Apify MCP server.

### Pricing

You are charged **per listing delivered** — see the price on this page. The listing details cost nothing extra, only time. Links that are not OfferUp searches and places OfferUp does not know are free.

### FAQ

**How many listings per search?** As many as OfferUp lets a search reach. A live run asked for every bike around Los Angeles, newest first, and got 8,739 different listings in under 4 minutes (without details). OfferUp's deep pages repeat listings they already showed; the run leaves the repeats out and stops when five pages in a row bring nothing new. Set **Max listings per search** as high as you need.

**Where does a search end?** Where OfferUp's own search area ends: past the listings within the chosen distance OfferUp goes on with "Found outside your search area", and the run stops there. New or open-box iPhone 15s at $200–700 within 20 miles of Phoenix gave 139 listings — all in Arizona, all new or open box, all inside the price range. A search reaches across state lines when the distance does (sofas within 20 miles of a Chicago ZIP code: 399 in Illinois, 1 in Indiana); the `city` and `state` fields say where each listing is.

**Are the filters obeyed?** Yes. In the live test run all 939 listings were inside their search's price range, and every iPhone had the chosen condition. OfferUp also places a few paid listings (`isPromoted: true`, 15 of the 939) among the results; they match the search too.

**Can I get items that ship?** The field is there, but OfferUp's web search is local: none of the 939 listings in the test run had shipping switched on.

**What about the text sellers write?** Titles and descriptions come as written, except that phone numbers (also ones hidden as "214\*\*470\*\*0858"), e-mail addresses and, for private sellers, street addresses are taken out. In the test run that touched 106, 9 and 22 of 939 listings.

**Why no phone numbers or seller names?** They are personal data — almost every OfferUp seller is a private person. Every listing has its `url`; buyers contact the seller on OfferUp.

**Is this affiliated with OfferUp?** No. This is an independent tool that reads public OfferUp listings.

**Like it?** A short review on the Store page helps other people find this Actor. Something missing or broken? Tell us on the Issues tab — we read every one.

# Actor input Schema

## `searchUrls` (type: `array`):

Set up a search on offerup.com with the filters you want and paste the address of the results page, one per line: a search (…/search?q=bike), a category (…/c/furniture) or a category or city page (…/c/furniture/in/austin-tx, …/in/seattle-wa). A link without a city searches around the places under "Locations".

## `keywords` (type: `array`):

Or search for these words, one per line — e.g. "sofa", "iphone 15". Each keyword is searched around each place under "Locations", with the filters below.

## `locations` (type: `array`):

US ZIP codes or cities to search around, one per line — e.g. 98101, "Austin, TX". Used for keywords and for links without a city. With no keywords and no links, you get everything for sale around each place (in the category below).

## `radiusMiles` (type: `string`):

For keywords and locations: how far from the place. OfferUp offers 5, 10, 20, 30 (its default) or 50 miles.

## `category` (type: `string`):

For keywords and locations: only this category.

## `minPrice` (type: `integer`):

For keywords and locations.

## `maxPrice` (type: `integer`):

For keywords and locations.

## `conditions` (type: `array`):

For keywords and locations: only items in these conditions.

## `sortBy` (type: `string`):

For keywords and locations. "Newest first" is the steadiest order for daily runs; "Best match" shuffles between runs.

## `maxListingsPerSearch` (type: `integer`):

Stops each search (each keyword or link around each place) after this many listings.

## `includeDetails` (type: `boolean`):

Description, condition, category, post date, firm price, shipping and the car's make, model and year. They come in one extra request per 50 listings, at no extra charge. Untick for a faster run with the search data only.

## `maxConcurrency` (type: `integer`):

How many searches to work on at the same time.

## `proxyConfiguration` (type: `object`):

Used only to try again after a network error: the first try goes out directly.

## Actor input object example

```json
{
  "searchUrls": [
    "https://offerup.com/search?q=mountain+bike"
  ],
  "locations": [
    "Seattle, WA"
  ],
  "maxListingsPerSearch": 30,
  "includeDetails": true,
  "maxConcurrency": 3,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Every result as a JSON record, with a status for each input.

## `resultsCsv` (type: `string`):

The same records as CSV, for a spreadsheet.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchUrls": [
        "https://offerup.com/search?q=mountain+bike"
    ],
    "locations": [
        "Seattle, WA"
    ],
    "maxListingsPerSearch": 30,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("highbrow_fame/offerup-listings").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchUrls": ["https://offerup.com/search?q=mountain+bike"],
    "locations": ["Seattle, WA"],
    "maxListingsPerSearch": 30,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("highbrow_fame/offerup-listings").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchUrls": [
    "https://offerup.com/search?q=mountain+bike"
  ],
  "locations": [
    "Seattle, WA"
  ],
  "maxListingsPerSearch": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call highbrow_fame/offerup-listings --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,highbrow_fame/offerup-listings"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/dMbxmpp2vRa6ba1dR/builds/2V9q8DWjd0AILQqBb/openapi.json
