# OfferUp Scraper (`maximedupre/offerup-marketplace`) Actor

Collect public OfferUp listings by keyword, search URL, or listing ID. Get asking prices and locations, with optional seller, photo, and vehicle details for resale and market research.

- **URL**: https://apify.com/maximedupre/offerup-marketplace.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** E-commerce, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.05 / 1,000 listings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

### 🛒 Compare public OfferUp listings

Resellers and market researchers can collect public US OfferUp listings with titles, asking prices, currency, and listing IDs. Add locations, photos, seller data, and vehicle facts when available to compare offers in a structured dataset without copying each page by hand.

- Find **[Used Furniture for Sale Near Me](https://apify.com/maximedupre/offerup-marketplace/examples/used-furniture-for-sale-near-me)** around a chosen search location.
- Collect **[OfferUp Free Stuff Near Me](https://apify.com/maximedupre/offerup-marketplace/examples/offerup-free-stuff-near-me)** listings to review zero-price offers.
- Search **[OfferUp Used Cars](https://apify.com/maximedupre/offerup-marketplace/examples/offerup-used-cars)** to compare public asking prices.
- Find listings with **[OfferUp Shipping](https://apify.com/maximedupre/offerup-marketplace/examples/offerup-shipping)** options shown in public data.
- Search **[OfferUp Parts](https://apify.com/maximedupre/offerup-marketplace/examples/offerup-parts)** to collect offers for parts research.

#### 📦 Listing prices and public details

Each row holds one public listing. The Actor saves the first eligible match and skips later matches for the same listing, even across different submitted values. Optional fields are included when OfferUp shows them. Search rows are kept if optional details cannot be read.

You can compare asking prices and conditions, group listings by public location, and review seller ratings or vehicle facts. Photos are source links; the Actor does not download or store image files. Vehicle facts come from the listing, not a VIN decoder or vehicle-history check.

#### ▶️ Run an OfferUp search or lookup

1. Choose **Keywords**, **Search or explore URLs**, or **Listing URLs or IDs**.
2. Add the values for that method. Fields for other methods are ignored.
3. For searches, choose shared location and search filters if needed.
4. Set **Maximum listings** if you want a cap. Turn on **Include listing details** when you need public item-page data.
5. Start the run and open the listings dataset.

No OfferUp login is needed. Keywords and search URLs share one set of filters per run. Use separate runs for searches that need different filters. Direct listing lookups always request available details and carry the detail charge when successful.

#### ⚙️ Input

Search filters apply only to Keywords and Search or explore URLs.

| Field | Type | What it does |
|---|---|---|
| `discoveryMethod` | string | Required. Choose `keywords`, `searchUrls`, or `listings`. |
| `keywords` | array of strings | Required for Keywords. All keywords share the same filters. |
| `searchUrls` | array of URL objects | Required for Search or explore URLs. URLs set the base search; shared filters apply to each URL. |
| `listings` | array of strings | Required for Listing URLs or IDs. Add public item URLs or listing IDs. Available details carry a separate charge. |
| `zipCode` | string | Five-digit US ZIP code for searches. Use this or coordinates, not both. |
| `coordinates` | object | Search center with both latitude and longitude. Use this or a ZIP code, not both. |
| `coordinates.latitude` | number | Latitude in decimal degrees, from -90 to 90. |
| `coordinates.longitude` | number | Longitude in decimal degrees, from -180 to 180. |
| `radiusMiles` | number | Search radius of zero or more miles. Requires a location here or in the URL. Uses approximate public locations. |
| `category` | string | OfferUp category ID from a public category URL. |
| `minPrice` | number | Minimum asking price in USD, inclusive and zero or more. |
| `maxPrice` | number | Maximum asking price in USD, inclusive. Must be at least `minPrice`. |
| `conditions` | array of strings | Choose `new`, `openBox`, `reconditioned`, `used`, `forParts`, or `other`. Leave blank for any condition. |
| `pickupOnly` | boolean | Keep listings whose public data confirms local pickup. False applies no pickup filter. |
| `shippingOnly` | boolean | Keep listings whose public data confirms shipping. False applies no shipping filter. If both delivery filters are true, listings must offer both. |
| `postedAfter` | string | Date in `YYYY-MM-DD` format. Keep listings posted on or after it; exclude listings without a public posted date. |
| `sortBy` | string | Order within each search: `relevance`, `newest`, `closest`, `priceAsc`, or `priceDesc`. Leave blank for source order. |
| `maxItems` | integer | Run-wide cap on qualifying listings, at least 1 when set. Leave empty to return all available results until the source is exhausted. Searches continue beyond the first page; there is no fixed upper limit in the schema. |
| `includeDetails` | boolean | Add public descriptions, photos, seller data, and vehicle facts to searches when available. Successful details carry a separate charge. Direct lookups always include available details. Valid listings remain if details are unavailable. |

**Successful default-input example**

This is the public input from the successful default-input run on the current beta build.

```json
{
  "discoveryMethod": "keywords",
  "keywords": [
    "bicycle"
  ],
  "pickupOnly": false,
  "shippingOnly": false,
  "maxItems": 10,
  "includeDetails": false
}
```

#### 🧾 Output

**Run output**

| Field | Type | What it does |
|---|---|---|
| `listings` | string | Opens saved listings in the dataset overview. |

**Listing row fields**

All methods use the same row shape. Only `listingId`, `title`, `price`, and `currency` are required. Other fields may be absent when OfferUp does not show them.

| Field | Type | What it does |
|---|---|---|
| `listingId` | string | OfferUp listing ID for matching exports. |
| `title` | string | Public listing title. |
| `price` | number | Current asking price. |
| `currency` | string | Currency code for the asking price. |
| `originalPrice` | number | Original asking price when shown. |
| `firmPrice` | boolean | Whether the source marks the price as firm. |
| `location` | object | Public listing location. Coordinates are approximate. |
| `location.city` | string | Public city name. |
| `location.state` | string | Public state name or code. |
| `location.zipCode` | string | Public ZIP code. |
| `location.latitude` | number | Approximate latitude in decimal degrees. |
| `location.longitude` | number | Approximate longitude in decimal degrees. |
| `condition` | string | Source-published item condition. |
| `description` | string | Public item description. |
| `primaryImageUrl` | string | Main image URL chosen by the source. |
| `photos` | array of objects | Public photos and available image sizes. |
| `photos.url` | string | Source URL for each photo. |
| `photos.width` | integer | Image width in pixels. |
| `photos.height` | integer | Image height in pixels. |
| `categoryPath` | array of strings | Category names from broad to specific. |
| `quantity` | integer | Source-published available quantity. |
| `postedAt` | string | Source-published creation date and time. |
| `editedAt` | string | Source-published edit date and time. |
| `availability` | string | Public availability state. |
| `removed` | boolean | Whether a successfully read listing is marked removed. |
| `seller` | object | Public seller profile and reputation. |
| `seller.id` | string | Seller ID for joining listings. |
| `seller.name` | string | Public seller name. |
| `seller.avatarUrl` | string | Seller profile image URL. |
| `seller.location` | string | Public seller location. |
| `seller.joinedAt` | string | Source-published join date and time. |
| `seller.activity` | string | Public activity text. |
| `seller.rating` | number | Source-published rating. |
| `seller.ratingCount` | integer | Number of ratings. |
| `seller.itemsSold` | integer | Source-published items-sold count. |
| `seller.business` | boolean | Whether the source labels a business account. |
| `seller.dealer` | boolean | Whether the source labels a dealer account. |
| `seller.verifications` | array of strings | Public verification labels. |
| `seller.phoneNumbers` | array of strings | Phone numbers the seller makes public. |
| `seller.websites` | array of strings | Website links the seller makes public. |
| `pickupAvailable` | boolean | Public local pickup availability. |
| `shippingAvailable` | boolean | Public shipping availability. |
| `shipping` | object | Public seller-paid shipping facts. |
| `shipping.sellerPaid` | boolean | Whether the source says the seller pays shipping. |
| `vehicle` | object | Public vehicle facts from the listing. |
| `vehicle.make` | string | Vehicle make. |
| `vehicle.model` | string | Vehicle model. |
| `vehicle.year` | integer | Model year. |
| `vehicle.mileage` | number | Published mileage. |
| `vehicle.mileageUnit` | string | Unit for mileage. |
| `vehicle.vin` | string | Publicly supplied vehicle identification number. |
| `vehicle.transmission` | string | Published transmission type. |
| `vehicle.drivetrain` | string | Published drivetrain. |
| `vehicle.fuelType` | string | Published fuel type. |
| `vehicle.titleStatus` | string | Published vehicle title status. |
| `vehicle.fuelEconomy` | string | Published fuel-economy information. |
| `vehicle.trim` | string | Published trim. |
| `vehicle.engine` | string | Published engine information. |
| `vehicle.bodyStyle` | string | Published body style. |
| `vehicle.color` | string | Published color. |

**Complete example listing**

This genuine row comes from a successful direct lookup on the current beta build.

```json
{
  "listingId": "1041ca53-a606-36da-8f3d-871e34799b36",
  "title": "Bike Rack For Seat Post",
  "price": 15,
  "currency": "USD",
  "originalPrice": 15,
  "firmPrice": false,
  "condition": "New",
  "description": "In excellent working condition",
  "quantity": 1,
  "postedAt": "2026-09-22T16:48:57.292Z",
  "availability": "LISTED",
  "removed": false,
  "pickupAvailable": true,
  "shippingAvailable": false,
  "photos": [
    {
      "url": "https://images.offerup.com/gECme_pWpftMJbV2qxCFCrQz1PE=/1920x1080/4680/4680ef1ce4704f0abbb91ebf0c035593.jpg",
      "width": 1920,
      "height": 1080
    },
    {
      "url": "https://images.offerup.com/pIwm4k4rMONh5zkytuAfq8k-_wc=/1920x1080/9841/9841c30201bc4241946b0a4629a34e2d.jpg",
      "width": 1920,
      "height": 1080
    },
    {
      "url": "https://images.offerup.com/pdIDwK4H7NwoGiVU2h1t8BBn1Bs=/1920x1080/1987/1987e53fd8414a16b011d91ed8590573.jpg",
      "width": 1920,
      "height": 1080
    }
  ],
  "primaryImageUrl": "https://images.offerup.com/77HjGz109nF25r_8bF5EhCN92lI=/444x250/4680/4680ef1ce4704f0abbb91ebf0c035593.jpg",
  "location": {
    "city": "Wichita",
    "state": "KS",
    "zipCode": "67204",
    "latitude": 37.742,
    "longitude": -97.365
  },
  "categoryPath": [
    "Sports & Outdoors",
    "Bikes & Cycling"
  ],
  "seller": {
    "id": "142612",
    "name": "Skylar",
    "avatarUrl": "https://images.offerup.com/ejnvmmxuy20NNRq4mpcrzRECZq4=/100x100/smart/9cbb/9cbb74041bf0493ead11447f652faf5a.jpg",
    "location": "Wichita, KS",
    "joinedAt": "2014-04-06T12:15:35Z",
    "activity": "Responds within 1 hour",
    "rating": 5,
    "ratingCount": 78,
    "itemsSold": 435,
    "business": false,
    "dealer": false,
    "verifications": [
      "TRUYOU"
    ]
  },
  "shipping": {
    "sellerPaid": false
  }
}
```

#### 💳 Pricing

This Actor uses pay-per-event pricing. A **Listing** charge applies to each unique public listing saved. **Listing details** is an extra charge when public item-page details are added to a saved listing, including direct lookups. Failed detail requests do not create a detail charge. Empty searches do not create listing charges. See the Store pricing panel for current rates and plan tiers.

#### 🔌 Integrations

Start runs and read the dataset through the Apify API. Export rows as JSON or CSV, schedule runs, or use Apify webhooks to connect finished runs to your workflow.

https://www.youtube.com/watch?v=bNACk1_S_6w\&list=PLObrtcm1Kw6MUrlLNDbK9QRg8VDJg0gOW\&index=4

#### ❓ FAQ

##### What if a listing has no details?

Valid search listings are kept when optional details are unavailable. Fields that the source does not show may be absent. Failed details are not charged as successful details.

##### Can I require both shipping and local pickup?

Yes. Turn on both filters. A listing must have public data that confirms both options. These filters apply only to searches.

##### Can each keyword use a different location or price range?

No. All searches in one run share the filters you set. Use separate runs for different filter sets.

##### What happens if the same listing appears twice?

The first eligible occurrence is saved right away. Later matches are skipped, and the saved row is not changed to collect later match data.

##### Does leaving Maximum listings empty collect every OfferUp listing?

It returns all available results until the source is exhausted. This covers what OfferUp exposes for your search, not a promise of full marketplace coverage. A set limit is a cap, not a promised count.

##### Can I use this to decode a VIN or check vehicle history?

The Actor returns vehicle facts published with the listing when available. It does not decode VINs, value vehicles, or verify vehicle history.

##### Do I need an OfferUp account?

No. The Actor reads public US OfferUp listings without login. It does not read private messages or perform purchases or account actions.

##### Where is the official OfferUp marketplace?

The source website is [OfferUp](https://offerup.com). This Actor exports public listing data from that marketplace.

### 📝 Changelog

**v0.0** (04-10-2026)

- Initial release.

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~offerup-marketplace/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Related Actors

- [Facebook Marketplace Listings Scraper](https://apify.com/maximedupre/facebook-marketplace-listings): Compare local listing prices and locations on another public marketplace.
- [eBay Seller Scraper](https://apify.com/maximedupre/ebay-seller-scraper): Review public seller reputation and active listing snippets on eBay.
- [Reverb Sold Listings](https://apify.com/maximedupre/reverb-sold-listings): Compare historical sold amounts for used musical gear.
- [OfferUp Marketplace Listings Scraper](https://apify.com/automation-lab/offerup-marketplace-listings-scraper): Collect OfferUp search listings for local market comparisons.
- [OfferUp Scraper — Listings, Sellers & Vehicle VINs](https://apify.com/memo23/offerup-marketplace-scraper): Collect OfferUp listing and seller data with public vehicle facts.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `discoveryMethod` (type: `string`):

Choose how to find public OfferUp listings.

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

Enter one or more keywords. All keywords use the same search filters. Required for Keywords.

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

Enter public OfferUp search or explore URLs. The URLs set the base search. Shared filters below apply to each URL. Required for Search or explore URLs.

## `listings` (type: `array`):

Enter public OfferUp item URLs or listing IDs, one per line. Required for Listing URLs or IDs. Public listing details are included when available and carry a separate charge.

## `zipCode` (type: `string`):

Search location for Keywords and Search or explore URLs. Enter five digits. Use a ZIP code or coordinates, but not both.

## `coordinates` (type: `object`):

Search location for Keywords and Search or explore URLs. Enter latitude and longitude. Use coordinates or a ZIP code, but not both.

## `radiusMiles` (type: `number`):

For Keywords and Search or explore URLs. Requires a search location here or in the URL. Distance uses approximate public locations.

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

For Keywords and Search or explore URLs. Enter the OfferUp category ID from a public category URL.

## `minPrice` (type: `number`):

For Keywords and Search or explore URLs. Include listings at or above this asking price.

## `maxPrice` (type: `number`):

For Keywords and Search or explore URLs. Include listings at or below this asking price. Must be at least the minimum price.

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

For Keywords and Search or explore URLs. Choose one or more source-published conditions. Leave blank for any condition.

## `pickupOnly` (type: `boolean`):

For Keywords and Search or explore URLs. Include only listings with public data that confirms local pickup. Leave unchecked to apply no pickup filter.

## `shippingOnly` (type: `boolean`):

For Keywords and Search or explore URLs. Include only listings with public data that confirms shipping. Leave unchecked to apply no shipping filter. If Local pickup only is also checked, listings must offer both.

## `postedAfter` (type: `string`):

For Keywords and Search or explore URLs. Include listings with a public posted date on or after this date. Listings without a posted date are excluded.

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

For Keywords and Search or explore URLs. Choose the order within each search. Leave blank to use the source order.

## `maxItems` (type: `integer`):

Stop after this many qualifying listings across the run. Leave blank to return all available results until the source is exhausted. Searches continue beyond the first page.

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

For Keywords and Search or explore URLs. Add public item-page details such as descriptions, photo galleries, seller data, and vehicle facts when available. Successful details carry a separate charge. Listing URLs or IDs always include available details. Valid listings are kept if details are unavailable.

## Actor input object example

```json
{
  "discoveryMethod": "keywords",
  "keywords": [
    "bicycle"
  ],
  "pickupOnly": false,
  "shippingOnly": false,
  "maxItems": 10,
  "includeDetails": false
}
```

# Actor output Schema

## `listings` (type: `string`):

View the saved OfferUp listings.

# 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 = {
    "discoveryMethod": "keywords",
    "keywords": [
        "bicycle"
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/offerup-marketplace").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 = {
    "discoveryMethod": "keywords",
    "keywords": ["bicycle"],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/offerup-marketplace").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 '{
  "discoveryMethod": "keywords",
  "keywords": [
    "bicycle"
  ],
  "maxItems": 10
}' |
apify call maximedupre/offerup-marketplace --silent --output-dataset

```

## MCP server setup

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

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/mHUBynCHLccIIQO5C/builds/CjsG7T04uzNShUtc0/openapi.json
