# OfferUp Scraper — Listings, Prices & Seller Data (`logiover/offerup-scraper`) Actor

Scrape OfferUp listings by keyword or URL. Extract title, price, location, condition, seller info, images, and shipping details. Supports filters for price, condition, and sort. No API key, no login.

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

## Pricing

from $3.50 / 1,000 results

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## OfferUp Scraper — Listings, Prices & Seller Data

Scrape OfferUp listings at scale by keyword or direct URL. Extract titles, prices, locations, conditions, seller profiles, images, and shipping details from the largest US local marketplace. No API key, no login required.

### What does OfferUp Scraper do?

This actor scrapes OfferUp's public search feed and listing detail pages to extract structured marketplace data. It uses OfferUp's server-rendered `__NEXT_DATA__` JSON payload — no browser required, no API key needed.

In **search mode**, it paginates through OfferUp's search results using the `nextPageCursor` mechanism, collecting up to 50 listings per page. Each page returns listing titles, prices, locations, conditions, images, and delivery flags. In **detail mode**, it fetches individual listing pages and extracts the full Apollo GraphQL cache, which includes descriptions, category trees, seller profiles with ratings, GPS coordinates, all listing images, posting dates, and shipping details.

The scraper supports OfferUp's native filters: price range, item condition (New, Used, Open box, Reconditioned, For parts), and sort order (recent first, price ascending/descending, closest, best match). Datacenter proxies work reliably.

### Who is it for?

- **Resellers and flippers** tracking local deals and price arbitrage opportunities across US markets
- **Market researchers** analyzing secondhand pricing trends, supply density, and category demand
- **E-commerce analysts** monitoring competitor pricing and inventory on the US local marketplace
- **Data scientists** building datasets of secondhand goods pricing, geography, and seller behavior
- **Lead generation teams** identifying high-volume sellers and business accounts on OfferUp

### Use cases

- **Price monitoring**: Track prices of specific product categories (electronics, furniture, vehicles) across different US cities to identify pricing trends and arbitrage opportunities
- **Market research**: Analyze listing density, average prices, and condition distribution for product categories to size the secondhand market
- **Competitor intelligence**: Monitor what resellers and business accounts are listing, their pricing strategies, and seller ratings
- **Inventory sourcing**: Find bulk deals and underpriced items by scanning recent listings with price filters and condition filters
- **Geographic analysis**: Map listing activity and pricing by location using extracted GPS coordinates and city data

### Why use OfferUp Scraper?

- **No API key, no login** — works out of the box with zero configuration on OfferUp's public pages
- **26 data fields** — extracts listing details, seller profiles, category trees, images, coordinates, and shipping info
- **Bulk pagination** — follows OfferUp's `nextPageCursor` to collect hundreds or thousands of listings per keyword
- **Built-in filters** — supports price range, condition, and sort order at the search level, reducing unnecessary data
- **Dual mode** — search by keyword for bulk collection, or provide direct URLs for full listing detail with descriptions and seller data
- **Export to CSV, JSON, Excel** — download results in any format, or connect to Google Sheets, Slack, Zapier, and Make

### What data can you extract?

The scraper extracts the following fields from OfferUp listings. Search mode populates the core fields; detail mode (via direct URLs) adds descriptions, categories, seller profiles, and full image galleries.

| Field | Type | Description |
|-------|------|-------------|
| listingId | string | Unique OfferUp listing identifier (UUID format) |
| title | string | Listing title as shown on OfferUp |
| price | number | Listing price in USD |
| location | string | City and state (e.g. "Los Angeles, CA") |
| condition | string | Item condition: New, Open box, Reconditioned, Used, For parts, Other |
| description | string | Full listing description text (detail mode only) |
| category | string | Top-level category (e.g. "Electronics & Media") |
| subcategory | string | Sub-category (e.g. "Cell phones & Accessories") |
| imageUrl | string | Primary listing image URL |
| imageCount | number | Total number of listing images (detail mode) |
| images | array | All listing image URLs at full resolution (detail mode) |
| url | string | Direct link to the listing on OfferUp |
| isFirmPrice | string | Whether the seller marked the price as firm |
| shippingAvailable | string | Whether shipping is available for this listing |
| localPickup | string | Whether local pickup is available |
| vehicleMiles | number | Mileage for vehicle listings |
| postDate | string | ISO date when the listing was posted (detail mode) |
| sellerName | string | Seller's display name (detail mode) |
| sellerId | string | Seller's OfferUp user ID (detail mode) |
| sellerRating | number | Seller's average rating out of 5 (detail mode) |
| sellerRatingCount | number | Number of ratings received (detail mode) |
| sellerJoinDate | string | When the seller joined OfferUp (detail mode) |
| latitude | number | Listing GPS latitude (detail mode) |
| longitude | number | Listing GPS longitude (detail mode) |
| quantity | number | Available quantity (detail mode) |
| searchTerm | string | The keyword that returned this listing |
| scrapedAt | string | ISO timestamp of when the data was scraped |

#### Example output (search mode)

```json
{
  "listingId": "b7a4da0d-f9ff-3320-a652-bd4dea75d12e",
  "title": "iPhone 12 64GB Factory Unlocked",
  "price": 300,
  "location": "The Bronx, NY",
  "condition": null,
  "description": null,
  "category": null,
  "subcategory": null,
  "imageUrl": "https://images.offerup.com/xANL-1U3BSOUbAFkIbYW2_lm3XI=/250x333/f3ab/f3ab8f599a724e188fed7f135306fd40.jpg",
  "imageCount": null,
  "images": null,
  "url": "https://offerup.com/item/detail/b7a4da0d-f9ff-3320-a652-bd4dea75d12e",
  "isFirmPrice": null,
  "shippingAvailable": "false",
  "localPickup": "true",
  "vehicleMiles": null,
  "postDate": null,
  "sellerName": null,
  "sellerId": null,
  "sellerRating": null,
  "sellerRatingCount": null,
  "sellerJoinDate": null,
  "latitude": null,
  "longitude": null,
  "quantity": null,
  "searchTerm": "iphone",
  "scrapedAt": "2026-09-09T12:00:00.000Z"
}
```

### How to use

#### Option A: Search by keyword

Search for listings across OfferUp using one or more keywords. The scraper paginates automatically and applies your filters.

1. Open the OfferUp Scraper on Apify Console
2. Enter one or more keywords in **Search Keywords** (e.g. `iphone`, `mountain bike`, `couch`)
3. Set **Max Results Per Search** to control how many listings to collect per keyword
4. Optionally set **Minimum/Maximum Price**, **Condition**, and **Sort By**
5. Click **Start** to run

```json
{
  "searchTerms": ["macbook pro", "dell laptop"],
  "maxResults": 500,
  "priceMin": 200,
  "priceMax": 1500,
  "condition": "USED",
  "sortBy": "-posted"
}
```

#### Option B: Scrape specific listing URLs

Provide direct OfferUp listing URLs to extract full detail including descriptions, seller profiles, and all images.

1. Open the OfferUp Scraper on Apify Console
2. Paste listing URLs into **Listing URLs** (e.g. `https://offerup.com/item/detail/b7a4da0d-f9ff-3320-a652-bd4dea75d12e`)
3. Click **Start** to run

```json
{
  "startUrls": [
    "https://offerup.com/item/detail/b7a4da0d-f9ff-3320-a652-bd4dea75d12e",
    "https://offerup.com/item/detail/70de5ee4-b14a-3e32-99ab-b24867b09e1d"
  ]
}
```

### Input parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| searchTerms | string\[] | `["iphone"]` | Keywords to search on OfferUp. Each keyword runs a separate paginated search. |
| startUrls | string\[] | `[]` | Direct listing URLs to scrape with full detail (description, seller, images). |
| maxResults | integer | `200` | Maximum listings per keyword. Set to `0` for unlimited. |
| priceMin | integer | `0` | Minimum price filter in USD. |
| priceMax | integer | `0` | Maximum price filter in USD. `0` = no limit. |
| condition | string | `""` | Condition filter: `NEW`, `OPEN_BOX`, `REFURBISHED`, `USED`, `BROKEN`, `OTHER`, or empty for any. |
| sortBy | string | `best_match` | Sort order: `best_match`, `-posted` (recent), `distance`, `price` (low-high), `-price` (high-low). |
| proxyConfiguration | object | Apify auto | Proxy settings. Datacenter proxies work well for OfferUp. |

#### Full input example

```json
{
  "searchTerms": ["nintendo switch", "ps5"],
  "startUrls": [],
  "maxResults": 300,
  "priceMin": 100,
  "priceMax": 400,
  "condition": "",
  "sortBy": "-posted",
  "proxyConfiguration": { "useApifyProxy": true }
}
```

### Output example

Full detail mode output (from a direct listing URL):

```json
{
  "listingId": "b7a4da0d-f9ff-3320-a652-bd4dea75d12e",
  "title": "iPhone 12 64GB Factory Unlocked",
  "price": 300,
  "location": "The Bronx, NY",
  "condition": "Used",
  "description": "iPhone 12 64GB Factory Unlocked\n\nBattery health:80%\n\nIt's a store pickup only!!",
  "category": "Electronics & Media",
  "subcategory": "Cell phones & Accessories",
  "imageUrl": "https://images.offerup.com/YBmAIK5zGdMKKEnYQxUvcnAi0Hg=/960x1280/f3ab/f3ab8f599a724e188fed7f135306fd40.jpg",
  "imageCount": 6,
  "images": [
    "https://images.offerup.com/YBmAIK5zGdMKKEnYQxUvcnAi0Hg=/960x1280/f3ab/f3ab8f599a724e188fed7f135306fd40.jpg",
    "https://images.offerup.com/2IlIgjhu8Ba3Tmo1v4b6w_5KZOg=/960x1280/9c80/9c80764abc9b4f738e26b1d86a0cc4bb.jpg"
  ],
  "url": "https://offerup.com/item/detail/b7a4da0d-f9ff-3320-a652-bd4dea75d12e",
  "isFirmPrice": "false",
  "shippingAvailable": "false",
  "localPickup": "true",
  "vehicleMiles": null,
  "postDate": "2026-09-08T18:26:37.366Z",
  "sellerName": "Throggs Neck Wireless & ELEC",
  "sellerId": "29428444",
  "sellerRating": 5,
  "sellerRatingCount": 175,
  "sellerJoinDate": "2017-05-26T00:37:53Z",
  "latitude": 40.882,
  "longitude": -73.83,
  "quantity": 1,
  "searchTerm": null,
  "scrapedAt": "2026-09-09T12:00:00.000Z"
}
```

### Tips for best results

- **Use specific keywords** — "macbook pro m2" returns more targeted results than "laptop". OfferUp's search works best with specific product names.
- **Combine keywords and filters** — Use `priceMin`/`priceMax` with `condition` to narrow down to exactly what you need and avoid wasting compute.
- **Sort by recent** — Set `sortBy` to `-posted` to get the freshest listings first, useful for deal monitoring.
- **Start with search mode** — Keyword search is fast (no per-listing requests). Use direct URLs only when you need descriptions and seller data.
- **Set reasonable maxResults** — Each search page returns ~50 listings. Setting `maxResults: 500` means ~10 pages per keyword, which runs in seconds.
- **Detail pages need US proxy** — If you use direct listing URLs and get geo-blocked, switch to the `BUYPROXIES94952` proxy group (US datacenter IPs).
- **Deduplicate across keywords** — The scraper automatically deduplicates listings across keywords within the same run.
- **Schedule regular runs** — Use Apify Scheduler to run daily or weekly and track new listings or price changes over time.
- **Check null fields** — Search mode returns core fields only. Fields like `description`, `sellerName`, and `images` are null in search mode — use direct URLs for those.
- **Monitor vehicle listings** — OfferUp has a large vehicles section. Use condition and price filters to find cars, and the `vehicleMiles` field for mileage data.

### Integrations

OfferUp Scraper integrates with the tools you already use:

- **Google Sheets** — automatically push scraped listings into a spreadsheet for tracking and analysis
- **Slack** — get notified when new listings matching your criteria are found
- **Zapier** — connect OfferUp data to 5,000+ apps (CRM, email, databases)
- **Make (Integromat)** — build automated workflows that trigger on new scraping results
- **Webhooks** — receive HTTP callbacks when a run finishes, with dataset download links
- **Schedule** — run the scraper on a recurring schedule (hourly, daily, weekly) to monitor listings

### API usage

Use the Apify API to run this scraper programmatically from any language.

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/logiover~offerup-scraper/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchTerms": ["iphone 15"],
    "maxResults": 100,
    "sortBy": "-posted"
  }'
```

#### Node.js

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

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('logiover/offerup-scraper').call({
    searchTerms: ['iphone 15'],
    maxResults: 100,
    sortBy: '-posted',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("logiover/offerup-scraper").call(run_input={
    "searchTerms": ["iphone 15"],
    "maxResults": 100,
    "sortBy": "-posted",
})
items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
print(f"Got {len(items)} listings")
```

### Use with AI agents (MCP)

OfferUp Scraper works with the Apify MCP server, letting AI agents like Claude search OfferUp listings and analyze marketplace data in natural language. Connect the Apify MCP server to your AI agent and ask questions like: "Find all iPhones under $200 on OfferUp and show me the cheapest 10 with their locations."

### FAQ

#### Does OfferUp Scraper require an API key or login?

No. This scraper works entirely with OfferUp's public pages. No API key, no account login, and no cookies are required. It extracts data from server-rendered HTML that OfferUp serves to any visitor.

#### What data does it extract from search results vs. detail pages?

Search mode extracts title, price, location, condition, image, shipping/pickup flags, and listing URL. Detail mode (direct URLs) adds the full description, category tree, seller name/rating/join date, GPS coordinates, all images, posting date, and quantity.

#### How many listings can I scrape in one run?

There is no hard limit. A typical search keyword returns 50 listings per page, and the scraper follows pagination automatically. You can collect thousands of listings per keyword. Set `maxResults` to control the volume.

#### Why do some fields show null in search mode?

Fields like `description`, `sellerName`, `category`, `postDate`, and `images` are only available on the detail page. In search mode, the scraper extracts only what OfferUp includes in the search feed. To get full data, provide the listing URL in `startUrls`.

#### Why am I getting zero results for detail URLs?

Detail pages may return "Geolocation Unavailable" when accessed from non-US IP addresses. Switch to the `BUYPROXIES94952` proxy group in the proxy configuration, which routes through US-based datacenter IPs.

#### What export formats are available?

You can download results as JSON, CSV, Excel (XLSX), XML, or RSS directly from the Apify Console. You can also connect to Google Sheets for automatic syncing.

#### How fast is the scraper?

Search mode is very fast — each page request returns ~50 listings and takes 1-2 seconds. A run collecting 500 listings typically finishes in under 30 seconds. Detail mode is slower since it makes one request per listing URL.

#### Is it legal to scrape OfferUp?

This scraper extracts only publicly available listing data that any visitor can see on offerup.com without logging in. The data is factual marketplace information (prices, titles, locations). Users are responsible for complying with applicable laws, OfferUp's Terms of Service, and data protection regulations in their jurisdiction.

#### Does OfferUp block scraping?

OfferUp's search pages work reliably with standard datacenter proxies. Detail pages may enforce geographic restrictions (US-only access). The scraper handles retries and proxy rotation automatically.

#### Can I filter by location or city?

OfferUp's search results are influenced by the proxy's geographic location. The scraper uses rotating datacenter proxies, so results may come from various US cities. For location-specific results, you can filter the output data by the `location` field.

#### How often is the data updated?

OfferUp listings are live and change frequently. Schedule the scraper to run hourly or daily to track new listings, removed listings, and price changes over time.

#### What are related scrapers I can use?

Check out these related scrapers for marketplace data:

- [Craigslist Scraper](https://apify.com/logiover/craigslist-scraper) — scrape classified listings from Craigslist
- [Facebook Marketplace Scraper](https://apify.com/logiover/facebook-marketplace-scraper) — extract listings from Facebook Marketplace
- [eBay Product Scraper](https://apify.com/logiover/ebay-product-scraper) — scrape product data and prices from eBay

### Is it legal?

This OfferUp Scraper extracts publicly available data from offerup.com. All extracted information — listing titles, prices, locations, images, and seller profiles — is data that any visitor can access without creating an account or agreeing to restricted terms. The scraper does not bypass any authentication, CAPTCHA, or access control mechanisms.

Users are solely responsible for ensuring their use of extracted data complies with applicable laws (including GDPR, CCPA, and other data protection regulations), OfferUp's Terms of Service, and any relevant intellectual property rights. Anthropic and the developer provide this tool for legitimate data collection purposes and do not endorse any use that violates third-party rights.

### Related scrapers

- [Craigslist Scraper](https://apify.com/logiover/craigslist-scraper) — classified listings from Craigslist across all US cities
- [Facebook Marketplace Scraper](https://apify.com/logiover/facebook-marketplace-scraper) — local marketplace listings from Facebook
- [eBay Product Scraper](https://apify.com/logiover/ebay-product-scraper) — product data, pricing, and seller info from eBay
- [Amazon Product Scraper](https://apify.com/logiover/amazon-product-scraper) — product details and reviews from Amazon

# Actor input Schema

## `searchTerms` (type: `array`):

List of keywords to search on OfferUp (e.g. "iphone", "couch", "mountain bike"). Each keyword runs as a separate search with full pagination.

## `startUrls` (type: `array`):

Direct OfferUp listing URLs to scrape (e.g. https://offerup.com/item/detail/...). Extracts full detail including description, seller info, and all images.

## `maxResults` (type: `integer`):

Maximum number of listings to extract per search keyword. Set to 0 for unlimited.

## `priceMin` (type: `integer`):

Filter listings with price at or above this value.

## `priceMax` (type: `integer`):

Filter listings with price at or below this value. Set to 0 for no limit.

## `condition` (type: `string`):

Filter by item condition.

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

Sort order for search results.

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

Apify proxy configuration. Datacenter proxies work well for OfferUp.

## Actor input object example

```json
{
  "searchTerms": [
    "iphone"
  ],
  "maxResults": 200,
  "priceMin": 0,
  "priceMax": 0,
  "condition": "",
  "sortBy": "best_match",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `listingId` (type: `string`):

No description

## `title` (type: `string`):

No description

## `price` (type: `string`):

No description

## `location` (type: `string`):

No description

## `condition` (type: `string`):

No description

## `description` (type: `string`):

No description

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

No description

## `subcategory` (type: `string`):

No description

## `imageUrl` (type: `string`):

No description

## `imageCount` (type: `string`):

No description

## `images` (type: `string`):

No description

## `url` (type: `string`):

No description

## `isFirmPrice` (type: `string`):

No description

## `shippingAvailable` (type: `string`):

No description

## `localPickup` (type: `string`):

No description

## `vehicleMiles` (type: `string`):

No description

## `postDate` (type: `string`):

No description

## `sellerName` (type: `string`):

No description

## `sellerId` (type: `string`):

No description

## `sellerRating` (type: `string`):

No description

## `sellerRatingCount` (type: `string`):

No description

## `sellerJoinDate` (type: `string`):

No description

## `latitude` (type: `string`):

No description

## `longitude` (type: `string`):

No description

## `quantity` (type: `string`):

No description

## `searchTerm` (type: `string`):

No description

## `scrapedAt` (type: `string`):

No description

# 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 = {
    "searchTerms": [
        "iphone"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("logiover/offerup-scraper").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 = { "searchTerms": ["iphone"] }

# Run the Actor and wait for it to finish
run = client.actor("logiover/offerup-scraper").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 '{
  "searchTerms": [
    "iphone"
  ]
}' |
apify call logiover/offerup-scraper --silent --output-dataset

```

## MCP server setup

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

```

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/u4k0fvZJgzk23LgYs/builds/GTeby0HmJ90mmaH13/openapi.json
