# OfferUp Scraper: Resale Data for Any US ZIP (`b2b_leads/offerup-real-time-data-scraper`) Actor

Live OfferUp resale data from any US ZIP code you choose: keyword listing search, full item details, seller inventory, profiles, sold comps, and instant Slack or JSON deal alerts. Pick your market, then stream structured JSON to your dataset in seconds.

- **URL**: https://apify.com/b2b\_leads/offerup-real-time-data-scraper.md
- **Developed by:** [Emmanuel](https://apify.com/b2b_leads) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.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.

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

## OfferUp Real-Time Data — Live Resale Market Intelligence

**Live OfferUp market data for vintage & thrift resellers:** keyword listing search in **any US market you choose by ZIP code**, full item details, seller inventory tracking, seller profiles, sold comps, and instant deal alerts. Structured JSON streams to your dataset row-by-row while the run is still working — results start appearing in seconds.

> ⚠️ **Free Apify plan notice:** Free-tier accounts are limited to **2 results per run**. Upgrade to any paid Apify plan for unlimited exports. This is stated here, in the Actor input form, and in the run log — it is a policy limit, not an error.

### Who this is for

- **Vintage & thrift resellers** sourcing undervalued inventory (cross-listers on Poshmark, eBay, Depop, Mercari, Grailed)
- **Consignment shop owners and pickers** tracking competitor inventory and local market prices
- **Resale arbitrageurs** hunting margin spreads on workwear, gorpcore, designer denim, furniture, and electronics
- **Fashion market researchers & pricing intelligence teams** tracking sell-through and trend data
- **AI agents & automations** that need structured resale market data through the Apify MCP server

### What you can do with it

- **Find undervalued thrift & vintage inventory** — search "carhartt detroit jacket", "vintage 90s levis 501", "patagonia fleece", "single stitch tee", "mid century lamp", or "y2k baby tee" and sort by just-listed to catch fresh steals before anyone else.
- **Source a market you don't live in** — set **Target location** to any 5-digit US ZIP code (`10001`, `90210`, `60601`, `78701`) and collect local inventory from that metro: great for remote picking, planning a buying trip, or comparing prices across cities.
- **Price comps & sell-through analysis** — pull sold and completed items to compute real market averages, sell-through rates, and realistic resale margins before you buy.
- **Seller inventory monitoring** — watch top sellers, thrift shops, and liquidators: their full active stock, new listings, and repricing moves.
- **Instant Slack / Discord deal alerts** — pipe every matched item to a webhook the moment it is saved, so your pricing bot or phone buzzes on newly listed steals.
- **Multi-platform pricing sync** — feed structured rows into Sheets, Airtable, Make, Zapier, n8n, or your own repricer.

### Target location — pick your market by ZIP code

OfferUp is a local marketplace: it shows what is available around **one** area, and buyers usually collect in person. By default that area follows the connection running the Actor, which can sit in a completely different city than you expect — that is why an untargeted run sometimes returns stock from another state.

Set **Target location** and the choice becomes yours. Give it any 5-digit US ZIP code and every keyword search returns listings from **that** area:

| Market you want to source | Target location |
|---|---|
| New York City | `10001` |
| Los Angeles / Beverly Hills | `90210` |
| Chicago | `60601` |
| Austin, TX | `78701` |
| Miami Beach, FL | `33139` |
| Phoenix, AZ | `85004` |

How it behaves:

- **Local distance is measured from your ZIP.** `10001` + 10 miles returns New York City listings; `90210` + 10 miles returns Los Angeles listings. The 50-mile maximum is the default and finds the most inventory.
- **It ships prefilled** with `10001` (New York) so a first run gives real, local results no matter where the connection sits. Swap in your own ZIP, or clear the field to keep the connection's own area. More starting points: `90210` Los Angeles, `60601` Chicago, `78701` Austin, `33139` Miami Beach, `85004` Phoenix, `97209` Portland, `30303` Atlanta, `19103` Philadelphia.
- **A city name is not enough.** A ZIP is exact and always pins to a real market, so use a ZIP (search *"your city zip code"* if you don't know it). A ZIP+4 like `90210-1234` works too — the four extra digits are ignored.
- **Every run confirms the area it locked onto**, e.g. `Target area resolved: Beverly Hills, CA 90210`, before any listings are collected.
- **Rows keep their own location too.** Each record still reports the listing's `local_area` and `distance_miles`, so per-item provenance is never lost.
- If a keyword has nothing in that area, the Actor says so in the log — naming the area it searched — and keeps going with your other keywords instead of failing.

### Features

| Feature | What it does | Output (`featureType`) |
|---|---|---|
| 🔍 **Listing Search** | Live keyword search with category, condition, distance, price filters, and any target location (US ZIP) | `listing_search` |
| ✨ **Full Details Enrichment** | Adds description, item specifics (Brand, Size, Color, Material), full view count, shipping options, and seller context **to the same search row** | `listing_search` (`detailsFetched: true`) |
| 📦 **Listing Details** | Full record for specific listings by URL or listing ID | `listing_details` |
| 🏪 **Seller Listings** | Full active inventory of any seller, thrift shop, or liquidator | `closet_listings` |
| 👤 **Seller Profile** | Seller stats: display name, verification, followers, local area, inventory size | `seller_profile` |
| 🧾 **Sold Item Comps / History** | Sold and completed items for market comps, margins, and sell-through | `sold_history` |
| 🔗 **Scrape By URL** | Direct processing of any OfferUp URL — search results, category page, seller inventory, or a single listing | `scrape_by_url` |

**Enrichment, not filtering:** when **Enrich with full listing details** is on, every search result stays **one row** and gains deep fields in place (`detailsFetched: true`). No duplicate rows, no dropped items — every discovered item always reaches the dataset, so your run cost stays predictable. Enrichment adds a little extra time per listing.

**Sold comps on a live marketplace:** OfferUp keeps a live inventory, so sold history is collected from sold-state listings on a seller's inventory plus any sold listing URLs/IDs you provide. The Actor tells you in the log when a seller has no sold items available right now instead of pretending otherwise.

### Quick start (10 results in seconds)

The Actor comes prefilled for an instant demo run:

1. Click **Start** — no configuration needed.
2. Defaults: Listing Search on, keywords `carhartt detroit jacket`, `vintage 90s levis 501`, `patagonia fleece`, **10 results per keyword**, **Local distance: Maximum (50 miles)**.
3. **Target location** comes prefilled with `10001` (New York), so the demo returns real New York listings immediately. Replace it with your own ZIP — `90210` Los Angeles, `60601` Chicago, `78701` Austin, `33139` Miami Beach — or clear it to search the connection's own area.
4. Watch the dataset fill row-by-row in real time.

#### Example resale searches that work well

| Goal | Keywords | Filters |
|---|---|---|
| Workwear flips | `carhartt detroit jacket`, `carhartt vest` | category: Clothing, Shoes, & Accessories |
| Vintage denim | `vintage 90s levis 501`, `levis 550 orange tab` | condition: Used |
| Gorpcore | `patagonia fleece`, `arc'teryx shell`, `north face nuptse` | max price: 60 |
| Y2K / streetwear | `y2k baby tee`, `vintage nba jersey`, `stussy 90s` | sort: Just listed |
| Furniture flips | `mid century lamp`, `walnut sideboard` | category: Home & Garden |
| Electronics arbitrage | `macbook pro 2019`, `nintendo switch oled` | condition: New / Open box |

### Full input reference

#### 🔍 Listing Search (`enableListingSearch`, default **on**)

| Field | Type | Default | Notes |
|---|---|---|---|
| `searchKeywords` | string list | 3 thrift examples | Required when search is on. Any OfferUp search term. |
| `searchLocation` | text | `10001` (New York) | **Target location** — 5-digit US ZIP code, prefilled with `10001` so the demo is local out of the box. Prefer `90210` (Los Angeles), `60601` (Chicago), `78701` (Austin), `33139` (Miami Beach)? Just type it. All keyword searches come from that area, and `searchRadius` is measured from it. Clear the field = the connection's own area. The run log names the resolved city, so you can confirm the area before trusting the rows. |
| `searchMaxResults` | integer | **10** | Max results per keyword (1–200). |
| `searchSort` | select | `relevance` | `relevance`, `newest` (just listed), `price_low_to_high`, `price_high_to_low`, `distance` (closest first). |
| `searchCategory` | select | All categories | Electronics & Media, Home & Garden, Clothing Shoes & Accessories, Baby & Kids, Vehicles, Toys Games & Hobbies. |
| `searchCondition` | select | Any | `NEW`, `OPEN_BOX`, `REFURBISHED`, `USED`, `BROKEN`, `OTHER` — the same values sellers pick when posting. |
| `searchMinPrice` / `searchMaxPrice` | integer | — | Price window in USD. |
| `searchRadius` | select | `50` (Maximum) | Local distance from `searchLocation` (or from the connection's area when no location is set): 5, 10, 20, 30, or 50 miles. Wider always finds more. |
| `searchFetchFullDetails` | boolean | `false` | **Enrich with full listing details** — merges description, item specifics, gallery, view count, shipping options, and seller context into the same row. |

#### 📦 Listing Details (`enableListingDetails`, default off)

| Field | Type | Notes |
|---|---|---|
| `listingUrls` | string list | Full item URLs (`https://offerup.com/item/detail/...`). |
| `listingIds` | string list | Listing IDs (the id at the end of an item URL). |

#### 🏪 Seller Listings (`enableSellerListings`, default off)

| Field | Type | Default | Notes |
|---|---|---|---|
| `sellerIds` | string list | — | Seller IDs (the numeric id in a seller's profile URL, e.g. `91145407`). Shared by Seller Listings, Seller Profile, and Sold Comps. Tip: every listing row this Actor exports includes the seller ID — feed one straight back in. |
| `sellerMaxListings` | integer | `30` | Max active listings per seller (1–500). |

#### 👤 Seller Profile (`enableSellerProfile`, default off)

Uses the same `sellerIds` list. One row per seller.

#### 🧾 Sold Item Comps / History (`enableSoldHistory`, default off)

Uses the same `sellerIds` list plus any `listingUrls` / `listingIds` you provide.

| Field | Type | Default | Notes |
|---|---|---|---|
| `soldMaxItems` | integer | `30` | How many of a seller's items to check for sold state (1–500). |

#### 🔗 Scrape By URL (`enableScrapeByUrl`, default off)

| Field | Type | Notes |
|---|---|---|
| `scrapeUrls` | string list | Any OfferUp search URL, category URL, seller profile URL, or single listing URL. The page type is detected automatically. |

#### Run volume

There is no single global cap — each feature section controls its own volume:

- **Listing Search** → `searchMaxResults` (per keyword)
- **Seller Listings** → `sellerMaxListings` (per seller)
- **Sold Comps** → `soldMaxItems` (per seller)
- **Listing Details** & **Scrape By URL** → the number of URLs/IDs you paste

#### 🔔 Delivery

| Field | Type | Default | Notes |
|---|---|---|---|
| `webhookUrl` | string | — | Optional. Every record is also POSTed here in real time. |
| `webhookFormat` | select | `json` | `json` (full record) or `slack` (Slack-ready message). |

#### 🌐 Connection

| Field | Type | Default | Notes |
|---|---|---|---|
| `proxyConfiguration` | proxy editor | Apify **RESIDENTIAL**, country `US` | Residential connections are strongly recommended — OfferUp localizes results by area, and residential connections deliver the most reliable results at scale. |

### Output schema (field reference)

One dataset row per item. Filter views by `featureType`: `listing_search`, `listing_details`, `closet_listings`, `seller_profile`, `sold_history`, `scrape_by_url`.

#### Identity & links

`item_id` — listing ID · `item_url`, `url` — item/seller URL · `featureType` — producing feature · `scrapedAt` — ISO timestamp · `position` — rank where found · `pageType` — detected page kind (URL feature)

#### Pricing

`current_price` · `original_price` · `currency` (USD) · `discount_percentage` · `price_drop_amount` · `is_firm_price` (seller marked price as firm)

#### Product

`title` · `description` · `condition` (New / Open box / Refurbished / Used / For parts / broken) · `condition_text` (raw marketplace value) · `category` · `item_specifics` (seller attribute pairs such as Brand, Size, Color, Material) · `brand` · `size` · `color` · `material` · `quantity` · `sku` · `views_count` · `is_newly_listed` (≤ 7 days) · `time_since_listed` · `badges`

#### Local marketplace context

`local_area` (city, state) · `distance_miles` · `distance_unit` · `local_pickup_available` · `shipping_available` · `shipping_options`

#### Images

`main_image_url` · `additional_image_urls`

#### Timing & lifecycle

`created_at` · `updated_at` · `sold_at` · `status` (`available` / `sold` / `reserved` / `not_for_sale` / `deleted`) · `is_sold` · `is_stale` · `is_removed` · `is_archived` · `is_unlisted`

#### Seller

`seller_id` · `seller_username`, `seller_display_name` · `seller_verified` · `seller_location`

#### Seller profile rows

`display_name` · `full_name` · `followers` · `total_listings` · `city` / `state` · `is_verified` · `inventory_has_more`

#### Run marker

`detailsFetched` — `true` when a search row was enriched in place (still one row per listing).

### Webhook integration

Every record is always written to the dataset. Add `webhookUrl` and each record is **additionally** POSTed in real time — perfect for instant deal alerts.

**Slack format** (`webhookFormat: "slack"`) — paste a Slack Incoming Webhook URL; messages render like:

```
:shopping_bags: *Carhartt Detroit Jacket XX-Large Brand New*
*Type:* listing_search  •  *Price:* USD 130  •  *Condition:* New  •  *Area:* SeaTac, WA  •  *Seller:* 93058422  •  11 views
<https://offerup.com/item/detail/...|Open on OfferUp>
```

**JSON format** (`webhookFormat: "json"`) — the full record object, one POST per row. Works with Discord (via /webhooks), Zapier, Make, n8n, or your own pricing bot:

```json
{
  "featureType": "listing_search",
  "title": "Carhartt Detroit Jacket XX-Large Brand New",
  "current_price": 130,
  "condition": "New",
  "views_count": 11,
  "local_area": "SeaTac, WA",
  "distance_miles": 4.2,
  "seller_id": "93058422",
  "item_url": "https://offerup.com/item/detail/...",
  "scrapedAt": "2026-09-27T12:00:00.000Z"
}
```

Webhook delivery is best-effort: a slow or failing webhook URL never blocks or breaks the run or the dataset writes.

### Using with AI agents (MCP)

The Actor works great through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) with Claude Desktop, Cursor, LangChain, or any MCP client:

1. In your MCP client config, add the Apify MCP server with your `APIFY_TOKEN`.
2. Expose this Actor as a tool (Actor ID: `~your-username/offerup-real-time-data`).
3. Ask natural-language questions like:
   - *"What is the average sold price for a 90s Carhartt J97 jacket on OfferUp?"*
   - *"Find Patagonia fleece listings under $30 posted today and Slack me the deals."*
   - *"Watch seller 91145407's inventory and tell me when they list Levis 501s under $25."*

The Actor returns clean, structured rows — no cleanup needed for LLM pipelines.

### Free-tier limits (paid-only features)

| Plan | Behavior |
|---|---|
| Free | Capped at **2 results per run** (default). The run finishes cleanly with a clear log message — this is a policy limit, not an error. |
| Any paid plan (Bronze+) | No caps — full output. |

Owner-side configuration (Apify Console → Actor → Environment variables, not visible to users):

- `FREE_TIER_MODE` = `limit` (default) or `block` (free users get 0 results with an upgrade message).
- `FREE_TIER_MAX_ITEMS` = `2` (default).

Paying users are detected automatically from platform run context — nothing to configure per-run.

### FAQ

**Do I need my own connection setup?**
No. The Actor ships preconfigured for Apify Residential, US default. Residential connections are recommended because OfferUp localizes results by area. If you use your own provider, point the proxy editor at it and keep the country set to US.

**Why did my free run stop at 2 items?**
That's the free-plan cap described above — it applies to every Apify Actor on the free plan. Upgrade to any paid Apify plan and the cap disappears automatically; no code or config change needed.

**How fresh is the data?**
Every run collects live data at the moment you press Start. "Just listed" sort plus webhooks is the recommended combo for deal-alert workflows. Typical usage: schedule runs every 5–30 minutes on watchlists.

**How do I get listings from a specific city?**
Set **Target location** to that city's 5-digit US ZIP code — `10001` for New York, `90210` for Los Angeles, `60601` for Chicago. Every keyword search then returns listings from that area, and **Local distance** is measured from it. The log confirms the resolved area (`Target area resolved: Chicago, IL 60601`) so you can verify it before reading the dataset. Leave the field empty to search the connection's own area instead.

**Why did my keyword come back empty?**
OfferUp is a local marketplace: a keyword with nothing available in the searched area returns nothing. Set **Target location** to a busier metro (e.g. `10001` or `90210`), widen **Local distance** to Maximum (the default), or try a broader keyword. The Actor logs a clear line — including the area it searched — when this happens and continues with your other keywords.

**Will I get rate-limited or blocked?**
The Actor paces keyword work with small randomized pauses, reuses a warmed-up session, retries on a fresh connection when a local area looks thin, and routes through residential connections — the same safeguards used at 10,000+ item scale. Keep concurrency defaults and it just works.

**What does "Enrich with full listing details" cost me in time?**
It adds a little extra time per listing to hydrate full product fields in the same row. With it off you get fast search cards (price, title, image, condition, area, pickup flag). Either way, every discovered item is saved — items are never filtered out.

**Can I track sellers instead of keywords?**
Yes — Seller Listings, Seller Profile, and Sold Comps all share the `sellerIds` list. Combined with a schedule, you get a competitor inventory feed and sell-through history. Every listing row includes the seller ID, so you can chain features in two runs.

**How do I compute sell-through rate?**
Pull Sold Comps for a seller, then divide sold items by (sold + active seller listings) for the same seller — both features use the same seller IDs, so one input drives both sides of the ratio.

**Is any raw source payload included?**
No — rows contain only the clean, structured fields documented above. There is no raw-data option and no internal payload dumps in webhooks.

**Does the run timeout?**
Runs support up to 10,000 seconds (about 2.7 hours) per run, which covers 10,000+ item exports at default pacing. For larger volumes, run multiple scheduled passes with smaller per-section limits.

### Pricing model

This Actor uses **Pay-Per-Event (PPE)**: you are charged one `result` event per dataset row saved. Set a max spend per run in Apify Console — when your limit is reached, the Actor stops gracefully, writes its summary, and exits cleanly without errors.

### Disclaimer

This Actor is not affiliated with, endorsed by, or sponsored by OfferUp. It provides access to publicly available marketplace information for research and business intelligence. Respect OfferUp's Terms of Service when using collected data.

***

*Built for the thrift & resale community. Happy flipping! 🧥*

# Actor input Schema

## `enableListingSearch` (type: `boolean`):

Live keyword search across OfferUp — thrift brands, streetwear, workwear, and vintage finds. On by default and prefilled so you can click Start and get results in seconds.

## `searchKeywords` (type: `array`):

One or more search terms, e.g. "carhartt detroit jacket", "vintage 90s levis 501", "patagonia fleece", "mid century lamp". Required when Listing Search is on.

## `searchMaxResults` (type: `integer`):

Maximum listings to return for each keyword (1–200). Default 10 — perfect for instant demo runs.

## `searchSort` (type: `string`):

"Just listed" is ideal for deal alerts on fresh inventory; "Closest first" is best for local pickup flips.

## `searchCategory` (type: `string`):

Limit the search to a top-level OfferUp category.

## `searchCondition` (type: `string`):

Filter by item condition — the same condition values OfferUp sellers pick when posting.

## `searchMinPrice` (type: `integer`):

Minimum listing price in USD.

## `searchMaxPrice` (type: `integer`):

Maximum listing price — pair with "Just listed" sort to catch underpriced steals fast.

## `searchLocation` (type: `string`):

Pick your market by ZIP code. Prefilled with 10001 (New York) so the demo run returns real, local listings right away — replace it with your own ZIP, or clear it to search the connection's own area instead. Enter any 5-digit US ZIP code — the city you source, flip, or resell in — and every keyword search returns listings from that area. More ZIPs to try: 90210 Los Angeles, 60601 Chicago, 78701 Austin, 33139 Miami Beach, 85004 Phoenix, 97209 Portland, 30303 Atlanta, 19103 Philadelphia. 'Local distance' below is measured from this ZIP, so 10001 + 10 miles gives New York City listings while 90210 + 10 miles gives Los Angeles listings. Use a ZIP rather than a city name — a ZIP always pins to a real market — and note a ZIP+4 like 90210-1234 also works. The run log names the area it locked onto, e.g. 'Target area resolved: Beverly Hills, CA 90210', so you can confirm it before reading the dataset.

## `searchRadius` (type: `string`):

How far out from your Target location above to search. If no Target location is set, it is measured from the connection's own area. OfferUp is a local marketplace, so wider distances find more inventory — Maximum (50 miles) is the default.

## `searchFetchFullDetails` (type: `boolean`):

When on, each search result stays ONE row (featureType listing\_search, detailsFetched=true) but is enriched with the full description, condition, item specifics, view count, photo gallery, shipping options, and seller details. Adds a little extra time per listing. When off, you get fast search cards with price, title, image, condition, and local area. Every discovered item is always saved — never filtered out.

## `enableListingDetails` (type: `boolean`):

Fetch the full record for specific OfferUp listings by URL or listing ID.

## `listingIds` (type: `array`):

OfferUp listing IDs, e.g. fd27264b-4ff8-31e4-af7c-8694782e253b.

## `listingUrls` (type: `array`):

Full OfferUp item URLs (https://offerup.com/item/detail/...).

## `enableSellerListings` (type: `boolean`):

Collect the full active inventory of any seller, thrift shop, or liquidator on OfferUp — track competitor stock and repricing moves.

## `sellerIds` (type: `array`):

OfferUp seller IDs (the numeric id in a seller's profile URL, e.g. 91145407). Shared by Seller Listings, Seller Profile, and Sold Comps. Tip: a seller ID is included on every listing row this Actor exports.

## `sellerMaxListings` (type: `integer`):

Maximum active listings to collect per seller (1–500).

## `enableSellerProfile` (type: `boolean`):

Extract seller stats: display name, verification, follower count, local area, and inventory size.

## `enableSoldHistory` (type: `boolean`):

Collect sold and completed listings for real market comps, resale margins, and sell-through analysis. OfferUp keeps a live inventory, so sold history is collected from sold-state listings on a seller's inventory plus any sold listing URLs/IDs you provide.

## `soldMaxItems` (type: `integer`):

Maximum sold listings to check per seller (1–500).

## `enableScrapeByUrl` (type: `boolean`):

Paste any OfferUp URL — search results, category page, seller inventory, or a single item listing.

## `scrapeUrls` (type: `array`):

Any OfferUp search, category, seller, or item URL.

## `webhookUrl` (type: `string`):

Optional. Every record is always saved to the run dataset — this webhook is an ADDITIONAL real-time push. Each new row is also POSTed to this URL (Slack, Discord, Zapier, Make, n8n, custom pricing bot).

## `webhookFormat` (type: `string`):

json = full record object; slack = Slack-friendly message payload.

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

Residential connections recommended — OfferUp localizes results by region, and residential connections deliver the most reliable results at scale.

## Actor input object example

```json
{
  "enableListingSearch": true,
  "searchKeywords": [
    "carhartt detroit jacket",
    "vintage 90s levis 501",
    "patagonia fleece"
  ],
  "searchMaxResults": 10,
  "searchSort": "relevance",
  "searchCategory": "",
  "searchCondition": "",
  "searchLocation": "10001",
  "searchRadius": "50",
  "searchFetchFullDetails": false,
  "enableListingDetails": false,
  "listingIds": [],
  "listingUrls": [],
  "enableSellerListings": false,
  "sellerIds": [],
  "sellerMaxListings": 30,
  "enableSellerProfile": false,
  "enableSoldHistory": false,
  "soldMaxItems": 30,
  "enableScrapeByUrl": false,
  "scrapeUrls": [
    "https://offerup.com/search?q=vintage%20carhartt"
  ],
  "webhookUrl": "",
  "webhookFormat": "json",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `allResults` (type: `string`):

Full dataset for this run (every featureType).

## `overview` (type: `string`):

Core fields across features, including detailsFetched for search rows.

## `search` (type: `string`):

featureType=listing\_search only. One listing = one row; full details are merged when "Enrich with full listing details" is enabled.

## `details` (type: `string`):

featureType=listing\_details — only from the Listing Details feature (specific IDs/URLs), not from search enrichment.

## `seller_listings` (type: `string`):

No description

## `seller_profile` (type: `string`):

No description

## `sold_history` (type: `string`):

No description

## `scrape_by_url` (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 = {
    "enableListingSearch": true,
    "searchKeywords": [
        "carhartt detroit jacket",
        "vintage 90s levis 501",
        "patagonia fleece"
    ],
    "searchMaxResults": 10,
    "searchSort": "relevance",
    "searchCategory": "",
    "searchCondition": "",
    "searchLocation": "10001",
    "searchRadius": "50",
    "searchFetchFullDetails": false,
    "enableListingDetails": false,
    "listingIds": [],
    "listingUrls": [],
    "enableSellerListings": false,
    "sellerIds": [],
    "sellerMaxListings": 30,
    "enableSellerProfile": false,
    "enableSoldHistory": false,
    "soldMaxItems": 30,
    "enableScrapeByUrl": false,
    "scrapeUrls": [
        "https://offerup.com/search?q=vintage%20carhartt"
    ],
    "webhookFormat": "json",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("b2b_leads/offerup-real-time-data-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 = {
    "enableListingSearch": True,
    "searchKeywords": [
        "carhartt detroit jacket",
        "vintage 90s levis 501",
        "patagonia fleece",
    ],
    "searchMaxResults": 10,
    "searchSort": "relevance",
    "searchCategory": "",
    "searchCondition": "",
    "searchLocation": "10001",
    "searchRadius": "50",
    "searchFetchFullDetails": False,
    "enableListingDetails": False,
    "listingIds": [],
    "listingUrls": [],
    "enableSellerListings": False,
    "sellerIds": [],
    "sellerMaxListings": 30,
    "enableSellerProfile": False,
    "enableSoldHistory": False,
    "soldMaxItems": 30,
    "enableScrapeByUrl": False,
    "scrapeUrls": ["https://offerup.com/search?q=vintage%20carhartt"],
    "webhookFormat": "json",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("b2b_leads/offerup-real-time-data-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 '{
  "enableListingSearch": true,
  "searchKeywords": [
    "carhartt detroit jacket",
    "vintage 90s levis 501",
    "patagonia fleece"
  ],
  "searchMaxResults": 10,
  "searchSort": "relevance",
  "searchCategory": "",
  "searchCondition": "",
  "searchLocation": "10001",
  "searchRadius": "50",
  "searchFetchFullDetails": false,
  "enableListingDetails": false,
  "listingIds": [],
  "listingUrls": [],
  "enableSellerListings": false,
  "sellerIds": [],
  "sellerMaxListings": 30,
  "enableSellerProfile": false,
  "enableSoldHistory": false,
  "soldMaxItems": 30,
  "enableScrapeByUrl": false,
  "scrapeUrls": [
    "https://offerup.com/search?q=vintage%20carhartt"
  ],
  "webhookFormat": "json",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call b2b_leads/offerup-real-time-data-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,b2b_leads/offerup-real-time-data-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/RHiEKUkhQw5b1xkSg/builds/RNFc2HmTgS2kiehKs/openapi.json
