OfferUp Marketplace Listings Scraper
Pricing
Pay per event
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
Maintained by CommunityActor 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
- Open the Actor input page.
- Add one or more search keywords, such as
iphoneorToyota Tacoma. - Enter a US ZIP code and radius.
- Optionally choose price, condition, delivery, category, and sort filters.
- Set a small
maxItemsvalue for the first run. - Click Start.
- Open the default dataset to preview or download the results.
For an existing OfferUp search, paste its /search or /explore URL into startUrls.
Input
| Field | Type | Purpose |
|---|---|---|
keywords | string array | Product, brand, or vehicle searches |
startUrls | URL array | OfferUp search or explore URLs |
zipCode | string | Five-digit US ZIP code |
radius | integer | 5, 10, 20, 30, or 50 miles |
categoryId | string | Optional OfferUp category identifier |
minPrice | number | Inclusive minimum USD price |
maxPrice | number | Inclusive maximum USD price |
conditions | string array | New, open box, refurbished, used, or broken |
delivery | string | All, local pickup, or shipping |
sortBy | string | Relevance, recent, closest, low price, or high price |
maxItems | integer | Global unique listing limit |
maxRequestRetries | integer | Attempts 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.
| Field | Description |
|---|---|
listingId | Stable OfferUp listing identifier |
url | Canonical OfferUp item URL |
title | Listing title |
price | Numeric asking price when available |
formattedPrice | Display-ready price |
currency | USD |
locationName | Public listing location |
condition | OfferUp condition label when available |
flags | Source fulfillment or listing flags |
localPickup | Local pickup signal |
shippingAvailable | Shipping signal |
imageUrl | Primary OfferUp image |
imageWidth / imageHeight | Source image dimensions |
isFirmPrice | Firm-price signal when supplied |
priceDrop | Price-drop signal when supplied |
vehicleMiles | Vehicle mileage when supplied |
searchQuery | Keyword that produced the listing |
sourceUrl | Search URL used by the Actor |
scrapedAt | UTC 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:
maxItemsis 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:
- sort by recent listings;
- keep
maxItemsproportional to expected new inventory; - store listing IDs in your destination system;
- treat unseen IDs as new inventory;
- 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 ApifyClientimport osclient = 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().itemsprint(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
listingIdvalues 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.
Is it legal to scrape OfferUp?
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.
Related marketplace scrapers
- Craigslist Scraper for US classifieds
- Kijiji Scraper for Canadian classifieds
- eBay Scraper for auction and marketplace products
- Wallapop Marketplace Scraper for Spanish second-hand listings
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.