OfferUp Marketplace Listings Scraper avatar

OfferUp Marketplace Listings Scraper

Pricing

Pay per event

Go to Apify Store
OfferUp Marketplace Listings Scraper

OfferUp Marketplace Listings Scraper

Search public OfferUp US marketplace listings by keyword, ZIP, filters, or search URL. Export prices, locations, conditions, delivery flags, images, IDs, and listing URLs without login.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Stas Persiianenko

Stas Persiianenko

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Search OfferUp and export public US marketplace listings as clean JSON, CSV, Excel, XML, or RSS.

Enter product keywords or OfferUp search URLs, choose a ZIP code and filters, and receive listing IDs, titles, prices, locations, conditions, pickup and shipping signals, images, firm-price signals, price-drop signals, and vehicle mileage when OfferUp provides them.

No OfferUp login, cookies, or user account is required.

What does OfferUp Marketplace Listings Scraper do?

The Actor turns OfferUp search results into structured records that are ready for spreadsheets, dashboards, databases, and monitoring jobs.

It can:

  • ๐Ÿ”Ž search several keywords in one run;
  • ๐Ÿ“ target a five-digit US ZIP code and radius;
  • ๐Ÿท๏ธ apply an OfferUp category identifier;
  • ๐Ÿ’ต constrain minimum and maximum price;
  • ๐Ÿ“ฆ select local pickup or shipping inventory;
  • ๐Ÿงฐ filter verified listing conditions;
  • โ†•๏ธ sort by relevance, recency, distance, or price;
  • ๐Ÿ” follow OfferUp pagination cursors;
  • ๐Ÿงน remove duplicate listing IDs across searches.

The result limit applies globally, so a run never intentionally saves more listings than requested.

Who is it for?

Resellers and arbitrage teams

Find newly listed local inventory, compare asking prices, and feed promising deals into sourcing workflows.

Dealers and inventory buyers

Track vehicles, tools, electronics, furniture, or other local stock around selected markets.

Market researchers

Capture scheduled snapshots for price distribution, assortment, availability, and geographic analysis.

Developers and data teams

Use stable fields and canonical item URLs in internal lead pipelines, alerts, enrichment jobs, or BI systems.

Why use this OfferUp scraper?

Manual OfferUp searching is useful for one-off browsing but difficult to repeat across many keywords or cities.

This Actor adds:

  • repeatable input and output contracts;
  • cursor pagination beyond the first visible screen;
  • exact ID deduplication;
  • local validation of price, condition, and delivery filters;
  • retries and session rotation for transient blocking;
  • Apify scheduling, webhooks, datasets, API access, and integrations.

It only exports public listing-search information and does not automate messaging or accounts.

How to scrape OfferUp listings

  1. Open the Actor input page.
  2. Add one or more search keywords, such as iphone or Toyota Tacoma.
  3. Enter a US ZIP code and radius.
  4. Optionally choose price, condition, delivery, category, and sort filters.
  5. Set a small maxItems value for the first run.
  6. Click Start.
  7. Open the default dataset to preview or download the results.

For an existing OfferUp search, paste its /search or /explore URL into startUrls.

Input

FieldTypePurpose
keywordsstring arrayProduct, brand, or vehicle searches
startUrlsURL arrayOfferUp search or explore URLs
zipCodestringFive-digit US ZIP code
radiusinteger5, 10, 20, 30, or 50 miles
categoryIdstringOptional OfferUp category identifier
minPricenumberInclusive minimum USD price
maxPricenumberInclusive maximum USD price
conditionsstring arrayNew, open box, refurbished, used, or broken
deliverystringAll, local pickup, or shipping
sortBystringRelevance, recent, closest, low price, or high price
maxItemsintegerGlobal unique listing limit
maxRequestRetriesintegerAttempts per page on transient blocks

Provide at least one keyword or start URL.

Invalid ZIP codes, non-OfferUp URLs, impossible price ranges, and unsupported target paths fail early.

Example input

{
"keywords": ["iphone", "macbook pro"],
"zipCode": "90001",
"radius": 30,
"minPrice": 50,
"maxPrice": 1000,
"delivery": "all",
"sortBy": "recent",
"maxItems": 40
}

A URL-based run can use:

{
"startUrls": [
{ "url": "https://offerup.com/search?q=mountain+bike" }
],
"zipCode": "98101",
"radius": 20,
"maxItems": 25
}

Output data

Each dataset row represents one OfferUp listing.

FieldDescription
listingIdStable OfferUp listing identifier
urlCanonical OfferUp item URL
titleListing title
priceNumeric asking price when available
formattedPriceDisplay-ready price
currencyUSD
locationNamePublic listing location
conditionOfferUp condition label when available
flagsSource fulfillment or listing flags
localPickupLocal pickup signal
shippingAvailableShipping signal
imageUrlPrimary OfferUp image
imageWidth / imageHeightSource image dimensions
isFirmPriceFirm-price signal when supplied
priceDropPrice-drop signal when supplied
vehicleMilesVehicle mileage when supplied
searchQueryKeyword that produced the listing
sourceUrlSearch URL used by the Actor
scrapedAtUTC extraction timestamp

Example output

{
"listingId": "54d2d5da-db7e-327a-a426-335d3b599f8f",
"url": "https://offerup.com/item/detail/54d2d5da-db7e-327a-a426-335d3b599f8f",
"title": "Apple iPhone",
"price": 250,
"formattedPrice": "$250",
"currency": "USD",
"locationName": "Los Angeles, CA",
"condition": null,
"flags": ["LOCAL_PICKUP"],
"localPickup": true,
"shippingAvailable": false,
"imageUrl": "https://images.offerup.com/example.jpg",
"vehicleMiles": null,
"searchQuery": "iphone",
"scrapedAt": "2026-07-24T00:00:00.000Z"
}

Nullable fields mean OfferUp did not provide that signal in the search feed.

How much does it cost to scrape OfferUp listings?

The Actor uses pay-per-event pricing.

  • Run start: $0.005
  • BRONZE listing price: $0.00012807 per saved listing
  • Higher Apify plans receive tiered volume discounts.

A 20-listing BRONZE run is approximately $0.0076 before any platform-specific limits or credits.

The dataset contains only charged, saved listings. Use maxItems to keep test and scheduled runs predictable.

Filters and fail-closed behavior

OfferUp may omit condition or fulfillment information from an individual search tile.

When you request a condition, local pickup, shipping, or numeric price boundary, the Actor keeps only records that can be verified against that boundary.

It does not guess missing values.

This avoids silently returning listings that violate a buyer workflow.

Pagination and deduplication

OfferUp returns an opaque cursor with each search feed.

The Actor replays that cursor with the same search session and stops when:

  • maxItems is reached;
  • the source returns no listing tiles;
  • no new cursor is available;
  • a cursor repeats;
  • the run charge limit is reached.

Listing IDs are deduplicated across all keywords and URLs in the run.

Scheduling an OfferUp monitor

Use an Apify schedule to run the same search hourly, daily, or weekly.

Recommended monitoring pattern:

  1. sort by recent listings;
  2. keep maxItems proportional to expected new inventory;
  3. store listing IDs in your destination system;
  4. treat unseen IDs as new inventory;
  5. send a webhook when the run succeeds.

The Actor itself returns current snapshots; long-term change history belongs in your database or automation flow.

Integrations

Google Sheets

Connect the run dataset to Sheets for sourcing queues and price review.

Make and Zapier

Trigger workflows from completed runs, then route new listing IDs to Slack, email, Airtable, or a CRM.

Webhooks

Receive run-completion events and fetch the dataset through the Apify API.

Cloud storage and BI

Export JSON or CSV into S3, BigQuery, Snowflake, Power BI, or another analytics stack.

API usage with Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/offerup-marketplace-listings-scraper').call({
keywords: ['iphone'],
zipCode: '90001',
radius: 30,
maxItems: 20,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

API usage with Python

from apify_client import ApifyClient
import os
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/offerup-marketplace-listings-scraper').call(run_input={
'keywords': ['mountain bike'],
'zipCode': '98101',
'radius': 20,
'maxItems': 25,
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)

API usage with cURL

curl -X POST \
"https://api.apify.com/v2/acts/automation-lab~offerup-marketplace-listings-scraper/runs?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"keywords":["gaming laptop"],"zipCode":"10001","radius":20,"maxItems":20}'

Fetch dataset items after the run succeeds:

$curl "https://api.apify.com/v2/datasets/DATASET_ID/items?clean=true&format=json"

Use with Apify MCP

Claude Code setup

$claude mcp add --transport http apify https://mcp.apify.com?tools=automation-lab/offerup-marketplace-listings-scraper

Claude Desktop, Cursor, and VS Code setup

Add this MCP JSON block to the appropriate Claude Desktop, Cursor, or VS Code MCP configuration:

{
"mcpServers": {
"apify": {
"url": "https://mcp.apify.com?tools=automation-lab/offerup-marketplace-listings-scraper"
}
}
}

Authenticate with your Apify account when prompted.

Example prompts:

  • โ€œRun the OfferUp listings scraper for used camera lenses near ZIP 94103.โ€
  • โ€œExport 30 recent Toyota Tacoma listings and summarize the asking prices.โ€
  • โ€œFind local-pickup power tools under $300 around Dallas.โ€

Tips for reliable runs

  • Start with 10โ€“20 listings while validating a new market.
  • Use specific phrases to reduce irrelevant inventory.
  • Use a larger radius for sparse products.
  • Avoid many broad keywords in one run when one focused query is enough.
  • Leave retries at the default unless logs show repeated transient blocks.
  • Schedule recent-first searches for inventory monitoring.
  • Use canonical listingId values for downstream deduplication.

Limitations

OfferUp is an evolving marketplace and can change its public feed or anti-bot controls.

The Actor uses US residential sessions because direct datacenter access may be blocked.

Search tiles do not always include condition, shipping, firm-price, price-drop, or mileage values.

V1 does not claim descriptions, full galleries, seller ratings, seller contact data, or posted timestamps because those require separately verified detail enrichment.

Results reflect the public inventory OfferUp returned at run time; deleted, sold, promoted, personalized, or region-limited listings can change later.

This Actor extracts public marketplace search data without logging into an account.

You are responsible for ensuring your use complies with applicable laws, OfferUp terms, contractual obligations, privacy rules, and intellectual-property rights.

Do not use the data for spam, harassment, discrimination, prohibited profiling, or attempts to contact people unlawfully.

Collect only what your workflow needs and apply suitable retention and access controls.

Troubleshooting

The run says no listings matched

Broaden the keyword or radius, remove strict condition/delivery filters, confirm the ZIP code, and try a small unfiltered run.

A strict filter intentionally excludes listings when OfferUp omits the field needed to verify it.

A request was blocked or throttled

The Actor retries and rotates residential sessions automatically. Review the log before raising maxRequestRetries; repeated retries increase time and proxy traffic.

A start URL is rejected

Only public offerup.com/search and offerup.com/explore URLs are accepted. Item, account, message, and external-domain URLs are outside this Actorโ€™s scope.

Some optional fields are null

Null means the current OfferUp search feed did not publish that signal. The Actor does not fabricate values.

Use separate actors when you need source-specific fields and then merge records downstream using your own normalization rules.

FAQ

Does it require an OfferUp account?

No. It reads anonymous public search data.

Can it scrape several cities?

Yes. Run multiple keyword/ZIP combinations as separate Actor runs or schedules so each market remains easy to monitor and price.

Does it scrape item descriptions or sellers?

Not in v1. Those detail fields are deliberately excluded until the detail route and its cost are independently verified.

Can I provide an OfferUp URL?

Yes, for public /search and /explore URLs. The Actor rejects unrelated paths and non-OfferUp hosts.

How do I avoid duplicates?

The Actor deduplicates exact listing IDs within each run. Store IDs between runs if your monitor also needs historical deduplication.

Why are condition-filtered results fewer?

OfferUp does not publish a condition on every search tile. The Actor fails closed rather than guessing that a missing value matches your requested condition.

Support

If a valid public OfferUp search produces an unexpected failure, share the run URL, sanitized input, expected behavior, and the relevant log excerpt through the Actor issue form.

Do not include private account credentials, messages, or personal data.