OfferUp Marketplace Listings Scraper avatar

OfferUp Marketplace Listings Scraper

Pricing

from $0.08 / 1,000 offerup listing extracteds

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

from $0.08 / 1,000 offerup listing extracteds

Rating

0.0

(0)

Developer

Stas Persiianenko

Stas Persiianenko

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

0.19 hours

Issues response

2 hours 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 after deduplication, local field filters, and radius verification. The Actor keeps following source cursors until it saves the requested number of qualifying listings, the source is exhausted, or the run charge limit is reached.

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
searchLatitude / searchLongitudeRequested ZIP-code centroid used as the distance origin
listingLocationLatitude / listingLocationLongitudePublic city centroid resolved from locationName (not an exact listing coordinate)
calculatedDistanceMilesGreat-circle miles between those two centroids
distanceCalculationMethodExplicit distance method identifier
appliedUpstreamRadiusMilesRadius confirmed by OfferUp's search response
radiusFallbackAppliedWhether a supported upstream superset was required
sellerTypeNative upstream seller_type query value, when provided
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.

The run's OUTPUT key-value-store record contains listingsFetched, uniqueListingsSeen, duplicate/local-filter/outside-radius counts, returnedItems, pages fetched, source-exhaustion status, and the final stop reason. listingsFetched counts listing tiles received from OfferUp before deduplication and local filtering.

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.

OfferUp's accepted distance values vary by marketplace category (for example, the vehicle feed currently offers 25, 80, 100, 200, or maximum distance). The Actor verifies the requested radius in OfferUp's response and, when that category rejects it, retries with the smallest advertised radius that covers it before excluding locations outside the user's requested radius.

Local distance is a Haversine great-circle calculation in statute miles from the public centroid of the requested ZIP to the closest public centroid resolved for OfferUp's City, ST label. OfferUp search tiles do not expose exact listing coordinates. Ambiguous or unresolvable location labels fail closed. The diagnostic coordinates, calculated distance, applied upstream radius, and fallback flag are returned on each accepted row.

Start-URL query parameters such as seller_type=C2C are preserved on the real upstream request, not merely copied into output metadata. The sellerType output field and source URL show the applied native value; they do not independently prove a seller's account classification.

Pagination and deduplication

OfferUp returns an opaque cursor with each search feed.

The Actor replays that cursor with the same search session. maxItems counts accepted, saved rows—not raw tiles—and collection continues after filtered rows. It stops when:

  • the requested qualifying 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. A broad vehicle keyword can also match parts or accessories; the search feed does not provide a reliable vehicle-only eligibility flag.

This Actor currently has no full-detail mode and our portfolio has no supported companion Actor for OfferUp item enrichment. Description, VIN, drivetrain, transmission, full gallery, seller-account evidence, and live listing state are therefore not returned by this version. A technical probe confirmed that the anonymous public item page can expose description, gallery, seller account flags, listing state, coordinates, drivetrain, and transmission, but values such as VIN remain seller/source-dependent and may be null. Productizing that route requires separate reliability, cost, pricing, and QA work; search results alone are not equivalent evidence for vehicle eligibility or valuation.

Results reflect the public inventory OfferUp returned at run time. The search feed and any future detail check are point-in-time observations; 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?

No. Full-detail enrichment is not a supported input or companion Actor today. Search output should not be treated as complete vehicle-eligibility or valuation evidence.

Which build contains the ZIP/radius fix?

Build 0.1.3 is the first fixed build. Normal runs should use the latest build tag to receive the fix plus later compatible repairs. For a reproducible snapshot, set the Apify run option build to 0.1.3; that pin intentionally will not receive later fixes. Build selection is a run option, not an Actor input field.

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.