# Poshmark Scraper - Listings, Sold Prices & Closets (`abotapi/poshmark-scraper`) Actor

Scrape Poshmark fashion-resale listings: keyword search, brand and category browse, sold listings with sold dates, seller closet stats (followers, following). Filters for department, condition and availability. Incremental monitoring, resume, MCP export.

- **URL**: https://apify.com/abotapi/poshmark-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Features:** Limited permissions
- **Stats:** 3 total users, 0 monthly users, 100.0% runs succeeded, 3 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.40 / 1,000 listing or seller records

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?

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

## Poshmark Scraper: Listings, Sold Prices & Seller Closets

Poshmark Scraper turns Poshmark into a clean secondhand-fashion data feed. Get listing details, sold prices with sold dates, seller closet profiles and social counts across every department and brand. Search by keyword, brand or seller closet, or paste specific listing, closet, brand, category or search links, then export to JSON, CSV or Excel, or pull the results straight into your app through the API.

### Why This Scraper?

- **Two ways to find data.** Search mode covers keywords, brands and seller closets with filters applied. URL mode reads any listing, closet, brand, category or search link exactly as pasted.
- **Sold listings with sold dates.** Switch Availability to Sold (or All) to pull sold-out listings alongside their sold date and quantity sold, the site's own price-history surface.
- **Seller closet profiles.** Add a seller username or closet link and get that seller's follower, following and listing counts, followed by every listing in the closet.
- **Detail enrichment on demand.** Turn it on to add the seller's full aggregate stats, the complete photo set and the shipping note to each listing, billed only for listings that were actually read.
- **Filters that are honest.** Availability, department, condition, price range and shipping are narrowed on the site's own servers. Filters the site would silently ignore, like size or color, are not offered.
- **Built for monitoring.** Incremental mode returns only new, updated and reappeared listings on repeat runs, and a refused run fails loudly instead of returning an empty dataset.
- **Resume large pulls.** Paste a previous run or dataset ID to continue an interrupted pull without paying to re-collect records it already has.

### Use Cases

- **Resale sourcing and arbitrage:** scan brand and keyword listings for underpriced items worth reselling.
- **Price and market research:** collect sold listings with their sold dates and last asking prices to see which similar items sell, and when.
- **Closet and competitor tracking:** monitor specific sellers' closets for new listings and price changes.
- **Fashion trend analysis:** build datasets of styles, brands, colors and conditions across departments and categories.
- **Deal alerting:** run Incremental mode on a saved search or brand to get only newly listed or price-changed items.

### Data You Get

> Sample shape: values are illustrative placeholders, not from a live record.

| Field | Example |
| --- | --- |
| `kind` | `"listing"` (also `"seller"` on closet profile records) |
| `recordId` | `"e1111111111111111111111a"` |
| `listingId` | `"e1111111111111111111111a"` |
| `url` | `"https://poshmark.com/listing/Sample-Wool-Coat-e1111111111111111111111a"` |
| `title` | `"Sample Brand Co Wool Coat"` |
| `brand` | `"Sample Brand Co"` |
| `size` / `sizeDisplay` / `condition` / `conditionLabel` | `"M"` / `"US M"` / `"nwt"` / `"New With Tags"` |
| `price` | `40.0` (the listing's asking price; on sold listings, the last asking price, not the private accepted-offer amount) |
| `originalPrice` | `120.0` |
| `currency` | `"USD"` |
| `availability` | `"available"` (also `"sold"`, `"coming soon"`) |
| `soldAt` / `soldQuantity` | `"2026-01-05T10:00:00-07:00"` / `1` (sold listings only) |
| `department` / `category` / `colors` / `styleTags` | `"Women"` / `"Coats & Jackets"` / `["Tan"]` / `["Vintage"]` |
| `description` | `"Barely worn wool coat, smoke-free home."` |
| `likeCount` / `commentCount` / `shareCount` | `12` / `2` / `4` |
| `sellerUsername` / `sellerName` | `"sample_seller"` / `"Sample Seller"` |
| `pictureUrls` | `["https://images.example.invalid/sample.jpg"]` |
| `shippingNote` | `"$6.49 Shipping"` (detail enrichment only) |
| `comments` | `[{"commentId", "text", "createdAt", "authorUsername", "authorName", "authorId"}]` (detail enrichment only; first `maxComments` visible buyer comments, default 20, maximum 500) |
| `sellerFollowers` / `sellerFollowing` | `500` / `40` (detail enrichment only) |
| `soldPrice` / `status` / `daysToSell` | `32` / `"sold_out"` / `9` (`soldPrice` and `daysToSell` on sold listings only) |
| `nwt` / `boutique` / `likesCount` / `commentsCount` / `thumbnailUrl` / `scrapedAt` | `true` / `false` / same values as `likeCount` / `commentCount`, a small cover image, and the scrape time (`nwt` needs the condition, present on search results) |
| `shippingCost` / `sellerLocation` / `sellerSoldCount` / `sellerAvgShipTime` | `6.49` / `"Austin, TX"` / `1594` / `1.08` days (detail enrichment only; location only when the seller shows one) |
| `_enrichmentFailed` | `false` (set only when detail enrichment is on; `true` means the page could not be read and the row is card-only) |
| `changeType` / `changedFields` | `"NEW"` / `[]` (incremental mode only) |

Seller records (`kind: "seller"`, one per closet scraped) carry `username`, `displayName`, `closetUrl`, `bio`, `city`, `state`, `joinedAt`, `lastActiveAt` and the same `followers` / `following` / `likes` / `shares` counts instead of listing fields.

### How to Use

1. Pick a **mode**: `search` (keywords, brands and seller closets) or `url` (paste specific links).
2. In search mode, add any combination of keyword searches, brands or closets, and apply the availability, department and condition filters. In URL mode, paste listing, closet, brand, category or search links.
3. **URL mode with the links field untouched now scrapes one example per shape** instead of nothing: the default is 12 real poshmark.com links (brand, brand pinned to a department, keyword search, filtered search, category leaf, category department root, category with condition filter, seller closet, filtered and sorted brand, paginated `max_id` brand, listing slug link, bare 24-hex listing id). Replace them with your own links before running. `m.poshmark.com` links are read as poshmark.com; short links (posh.mk) and non-Poshmark links are skipped with a per-link warning in the log.
4. Set **Max items** to control run size and cost, then click **Start**.
5. Download the dataset as JSON, CSV or Excel, or read it through the API.

**Keyword search:**

```json
{
  "mode": "search",
  "searchQueries": ["wool coat"],
  "maxItems": 20
}
```

**Sold listings from one brand, one department:**

```json
{
  "mode": "search",
  "brands": ["Madewell"],
  "availability": "sold_out",
  "department": "Women",
  "maxItems": 50
}
```

**Watch a seller's closet for new listings:**

```json
{
  "mode": "search",
  "closets": ["sample_seller"],
  "incrementalMode": true,
  "stateKey": "seller-watch"
}
```

**Paste a link, with detail enrichment on:**

```json
{
  "mode": "url",
  "listingInputs": ["https://poshmark.com/brand/Madewell"],
  "fetchDetails": true,
  "maxItems": 10
}
```

#### Run it from your code

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/poshmark-scraper").call(run_input={"mode": "search", "searchQueries": ["wool coat"], "maxItems": 20})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], item["price"])
```

JavaScript:

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/poshmark-scraper').call({ mode: 'search', searchQueries: ['wool coat'], maxItems: 20 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the **Integrations** tab.

#### How Max items shapes a run

Every target (a keyword, brand or closet) gets an even share of Max items. A target's own walk stops when its share is spent, or when it reaches the site's own end (an empty page, or no further page cursor), whichever comes first. Shares round down and a share one target leaves unused is not handed to the next, so a run can return fewer records than Max items. With closets, the seller record takes one slot of that closet's share. Detail enrichment reads one extra page per listing that is actually pushed and carries its own small surcharge; leave it off unless you need the seller's full stats, the complete photo set or the shipping note.

#### Resume and recurring updates

- **Resume** (`resumeFromRunId`) continues one interrupted run: paste its run or dataset ID and the actor skips every record id already collected there, so you don't pay twice.
- **Incremental mode** (`incrementalMode`) is for running the same search, brand or closet again and again, for example daily. Each record is classified `NEW`, `UPDATED` (with `changedFields`), `UNCHANGED` (suppressed and not billed unless `emitUnchanged` is on), `REAPPEARED`, or `EXPIRED` (only with `emitExpired` on, and only after a run whose every target finished cleanly). When you turn on `emitExpired`, set Max items to `0` so every target is scanned to its end: listings a capped run never reached can otherwise be reported as `EXPIRED`. A listing is `UPDATED` when any returned field changes (price, availability, title, description, photos, likes, shares, comment count `commentCount`, seller details). These fields are always left out of the change check and `changedFields` but stay in the output: the nested `comments` list (new buyer comments alone do not make a listing `UPDATED`), `scrapedAt`, `_enrichmentFailed`, and the derived copies `soldPrice`, `status`, `nwt`, `likesCount`, `commentsCount`, `thumbnailUrl`, `daysToSell` and `shippingCost` (each repeats a field that is already compared). Add field names to `ignoreFieldsForChanges` to leave noisy ones (such as `likeCount`) out of the comparison and `changedFields` while keeping them in the output. A run that starts from a pasted link in the middle of a walk (a `max_id` or `page` cursor) never reports `EXPIRED`, because it covers only part of the tracked listings. `stateKey` names or shares a monitoring campaign; leave it empty and the actor derives one automatically from your targets and filters. With incremental mode off, output is exactly as before.

Resume and Incremental mode solve two different problems: Resume continues one specific run that got interrupted, while Incremental mode is for scheduling the same search repeatedly and getting only what changed.

#### Output views

The dataset has four tabs. **Results** shows every listing and seller field. **Listing details** shows the enrichment fields (seller stats, photos, shipping, buyer comments). **Changes** shows `changeType`, `changedFields` and first and last seen times for incremental runs. **Sellers** shows closet profiles. A run summary is saved under the `OUTPUT` key of the run's key-value store.

### Send results into your apps (MCP connectors)

Send results into the apps you already use via MCP connectors (Model Context Protocol). Authorize a connector under Apify, Settings, API & Integrations, then select it here: Notion gets a rich page per item, other connectors get a best-effort write. The export writes a condensed, human-readable summary per record (a title plus key fields), not the full JSON; the complete record always stays in the Apify dataset. Leave `mcpConnectors` empty to skip this entirely.

### Input Parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `mode` | string | `search` | `search` for keywords, brands and closets, or `url` for pasted links. |
| `searchQueries` | array | `["tote bag"]` | Search mode: keywords to search, one entry per search. |
| `brands` | array | (none) | Search mode: brand names or brand-page paths. |
| `closets` | array | (none) | Search mode: seller usernames or closet links. Each emits the seller's profile followed by that closet's listings. |
| `availability` | string | `available` | `available`, `sold_out`, or `all`. All availability includes dropping-soon items. |
| `department` | string | (none) | Keep listings from one department only. Leave empty for all departments. |
| `condition` | string | (none) | Keep listings in one condition tier only: New With Tags, Like New, Good, or Fair. |
| `brand` | string | (none) | Search mode: one brand, same as adding one entry to `brands`. |
| `minPrice` | number | (none) | Keep listings priced at or above this USD amount (whole dollars). Applied by the site. |
| `maxPrice` | number | (none) | Keep listings priced at or below this USD amount (whole dollars). Applied by the site. |
| `shippingFilter` | string | `all` | `all`, `free`, or `discounted_free` (free or discounted shipping). |
| `sortBy` | string | `relevance` | `relevance`, `newest` (most recently listed first; the site has no sort by sale date, and a saved `sold_recently` value is read as `newest`), `price_asc`, `price_desc`, `likes`. |
| `listingInputs` | array | 12 sample links, one per URL shape | URL mode: listing links or bare listing ids, closet links, brand links, category links or search links. |
| `urls` | array | same 12 sample links | Alias for `listingInputs`, accepted under the name other Apify actors use. |
| `fetchDetails` | boolean | `false` | Read each listing's own page and merge seller stats, the full photo set and the shipping note. Adds a per-listing surcharge when on. |
| `maxComments` | integer | `20` | With detail enrichment on, how many visible buyer comments to keep per listing (maximum 500). |
| `maxItems` | integer | `20` | Stop after this many records (`0` = no limit). Sellers count as records too when closets are scraped. |
| `resumeFromRunId` | string | (none) | Paste a previous run ID or dataset ID to continue a large pull without returning items already collected there. |
| `incrementalMode` | boolean | `false` | Turn this on for daily or recurring monitoring. Returns only new, updated and reappeared records on repeat runs. |
| `stateKey` | string | (none) | Optional. Name a monitoring campaign to keep its state stable, or share state across differently configured runs. |
| `emitUnchanged` | boolean | `false` | Also return (and bill) records that have not changed since the last run. |
| `emitExpired` | boolean | `false` | Also return (and bill) records no longer found, once a run has fully scanned every tracked target. Use with Max items `0`. |
| `ignoreFieldsForChanges` | array | (none) | Field names that should not make a listing count as UPDATED (for example `likeCount`). They stay in the output; they are left out of the change check and `changedFields`. |
| `mcpConnectors` | array | (none) | Optional: send a summary of each record to apps you authorized under Integrations. |
| `notionParentPageUrl` | string | (none) | Notion connector only: page under which item pages are created. |
| `maxNotifyListings` | integer | `50` | Cap on items written to each connector per run. Does not affect the dataset. |
| `proxyConfiguration` | object | Apify Proxy | Connection settings. The default standard pool works; no special proxy group is required. |

### Output Example

> Sample shape: values are illustrative placeholders, not from a live record.

```json
{
  "kind": "listing",
  "recordId": "e1111111111111111111111a",
  "listingId": "e1111111111111111111111a",
  "url": "https://poshmark.com/listing/Sample-Wool-Coat-e1111111111111111111111a",
  "title": "Sample Brand Co Wool Coat",
  "brand": "Sample Brand Co",
  "brandPath": "Sample-Brand-Co",
  "size": "M",
  "sizeDisplay": "US M",
  "condition": "nwt",
  "conditionLabel": "New With Tags",
  "price": 40.0,
  "originalPrice": 120.0,
  "currency": "USD",
  "availability": "sold",
  "soldAt": "2026-01-05T10:00:00-07:00",
  "soldQuantity": 1,
  "department": "Women",
  "category": "Coats & Jackets",
  "colors": ["Tan"],
  "description": "Barely worn wool coat, smoke-free home.",
  "likeCount": 12,
  "commentCount": 2,
  "shareCount": 4,
  "sellerUsername": "sample_seller",
  "sellerName": "Sample Seller",
  "sellerUrl": "https://poshmark.com/closet/sample_seller",
  "pictureUrls": ["https://images.example.invalid/sample.jpg"]
}
```

### Plan Requirement

An Apify plan with proxy access is required: the site refuses plain connections from datacenter and cloud addresses often enough that the default proxy setting, a standard rotating pool, is what the actor is built around. It was not confirmed that a datacenter-only setup works, so do not rely on one. The actor retries automatically with a different connection profile and exit when one is refused. Refusals also come in short windows: after a burst of rapid requests the site can refuse everything for about two minutes, and a run that hits one can return fewer records than Max items or, if every request is refused, stop with a clear message (see the FAQ). On a free Apify plan, which has no proxy access, the run stops with a message saying a paid plan or your own proxy URLs are needed. Detail enrichment reads one extra page per listing and carries its own small surcharge, shown on the Pricing tab; leave it off unless you need the seller's full stats, the complete photo set or the shipping note.

### FAQ

#### How much does it cost?

You pay per record returned (listing, sold listing or seller record), plus a small per-listing charge for detail enrichment, billed only for listings whose detail page was actually read and pushed. Unchanged, suppressed and failed records are never billed. The **Pricing** tab always shows the current rates. Use **Max items** to cap the cost of any run.

#### Is it legal to scrape Poshmark?

This actor collects only publicly available marketplace data. You are responsible for how you use it: follow Poshmark's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Listing details are generally facts, but photos and seller-submitted text may be subject to third-party rights.

#### Can I get only new or changed listings on a schedule?

Yes. Schedule the actor from the **Schedules** tab and turn on **Incremental mode**. Each run then returns only new, updated and reappeared records, and unchanged ones are not billed unless you turn on Emit unchanged.

#### What is the difference between Resume and Incremental mode?

They solve two different problems. **Resume** continues ONE specific run that got interrupted, using its run or dataset ID so you don't pay to re-collect what it already has. **Incremental mode** is for running the same search, brand or closet again and again, for example daily, and getting only what changed.

#### Why did my run fail instead of returning an empty dataset?

If every request the run made was refused or unreadable, the run ends as failed with a clear message ("Could not load any results page ... This is a connection problem, not an empty search", or a proxy-access message on plans without proxy) so "no matching listings" is never confused with "nothing could be read". The site sometimes refuses all requests for about two minutes after rapid pulls; wait a few minutes and run again. If only some targets or pages could be read, you still get what was found, and the run still succeeds.

#### Is the sold price what the buyer paid?

No. On sold listings `price` and `soldPrice` are the last asking price. Poshmark does not show the accepted-offer amount, so the real sale price can be lower.

#### Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

### 🔗 Want more classifieds data?

Pair this actor with these related scrapers from the same team:

<table>
<tr><td>🏷️ <a href="https://apify.com/abotapi/thredup-scraper"><b>ThredUp Scraper</b></a><br>Scrape ThredUp resale listings by keyword, department, brand, size, condition, price or...</td><td>🏷️ <a href="https://apify.com/abotapi/vinted-marketplace-scraper"><b>Vinted Multi-Country Scraper</b></a><br>Scrape Vinted across 27 country marketplaces: keyword search with brand, price and...</td></tr>
<tr><td>⚽ <a href="https://apify.com/abotapi/whatnot-scraper"><b>Whatnot Scraper</b></a><br>Scrape Whatnot live and upcoming shows, queued items and lots, and seller profiles...</td><td>👗 <a href="https://apify.com/abotapi/klekt-com-scraper"><b>KLEKT Sneaker &amp; Apparel Resale Scraper</b></a><br>Scrape sneaker and streetwear listings from KLEKT (klekt.com). Browse the catalog with...</td></tr>
<tr><td>🏷️ <a href="https://apify.com/abotapi/daangn-scraper"><b>Daangn Scraper</b></a><br>From $1/1K. Scrape Daangn (당근) marketplace listings by keyword and region. Returns 35+...</td><td>🏷️ <a href="https://apify.com/abotapi/kleinanzeigen-de-scraper"><b>Kleinanzeigen.de Scraper</b></a><br>From $1/1K. Scrape Kleinanzeigen.de ads by keyword, category, location, price, seller...</td></tr>
</table>

👉 [Browse all abotapi scrapers](https://apify.com/abotapi)

### 💬 Support

- 🐞 **Found a bug or a missing field?** Open a ticket on the [Issues tab](https://apify.com/abotapi/poshmark-scraper/issues/open). We usually reply within hours.
- 🛠️ **Need another site, extra fields or a private build?** Email <contact@abotapi.com>.
- ⭐ **Enjoying it?** A quick review on the actor page helps other users find it.

# Actor input Schema

## `mode` (type: `string`):

Search mode walks keyword searches, brand pages and seller closets forward, filters applied. URL mode reads the specific listing, brand, closet, category or search links you paste; the search-mode filter fields are ignored there.

## `searchQueries` (type: `array`):

Search mode: keywords to search, one entry per search (for example: tote bag, wool coat). Leave empty if you only want brands or closets.

## `brands` (type: `array`):

Search mode: brand names or brand-page paths (for example: Madewell, or Madewell-Women to pin a department). Leave empty if you only want keyword searches or closets.

## `brand` (type: `string`):

Search mode: one brand name or brand-page path (for example: Madewell). Same as adding one entry to the Brands list above.

## `closets` (type: `array`):

Search mode: seller usernames or closet links. Each emits the seller's profile (followers, following, listing counts) followed by that closet's listings.

## `availability` (type: `string`):

Keep Available for live listings, or Sold to pull sold listings with their sold dates (the source's price-history surface). All availability includes dropping-soon items.

## `department` (type: `string`):

Keep listings from one department only. Leave empty for all departments.

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

Keep listings in one condition tier only: New With Tags, Like New, Good, or Fair. Leave empty for all conditions.

## `minPrice` (type: `number`):

Keep listings priced at or above this many dollars (rounded down to whole dollars). Leave empty for no minimum. Search mode; the site applies it server-side.

## `maxPrice` (type: `number`):

Keep listings priced at or below this many dollars (rounded up to whole dollars). Leave empty for no maximum.

## `shippingFilter` (type: `string`):

All listings, only listings with free shipping, or listings with free or discounted shipping.

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

Result order (search mode). Newest = most recently listed first; the site has no sort by sale date. Price and likes sort across the whole result set.

## `listingInputs` (type: `array`):

URL mode: listing links or bare listing ids, closet links, brand links, category links or search links. Each target is walked forward on its own.

## `urls` (type: `array`):

Alias for Links, accepted under the name other Apify actors use for URL mode.

## `fetchDetails` (type: `boolean`):

Read each listing's own page and merge the seller's follower/following/listing counts, the full photo set and the shipping note into the record. Off by default; when on, each enriched listing carries a small per-listing surcharge (see pricing).

## `maxComments` (type: `integer`):

With detail enrichment on, attach up to this many buyer comments to each listing (default 20, 0 = none). Comments come from the page already read for enrichment, so they add no requests.

## `maxItems` (type: `integer`):

Stop after this many records (default 20; 0 = no limit). The run then stops when each target's walk reaches the site's own end. Sellers count as records too when closets are scraped.

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

Apify Proxy settings. The default standard pool works; no special proxy group is required.

## `resumeFromRunId` (type: `string`):

Paste a previous run ID or dataset ID to continue a large pull without returning items already collected there.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring. The first run returns every matching listing as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED listings. A listing counts as UPDATED when any returned field changes (for example price, availability, title, description, photos, likes, shares or seller details); UPDATED rows list the changed fields in changedFields. Always left out of the change check (they stay in the output): comments (the nested buyer comments list; the comment count commentCount is compared), scrapedAt, \_enrichmentFailed, and the derived copies soldPrice, status, nwt, likesCount, commentsCount, thumbnailUrl, daysToSell and shippingCost (each repeats a field that is already compared). Use Ignore fields when detecting changes to leave out more. Turn on Emit unchanged or Emit expired only when you also want those rows returned (and billed). State is kept separately for each keyword, brand, closet and filter setup; use State key to name or deliberately share a monitoring campaign.

## `stateKey` (type: `string`):

Optional. Name this monitoring campaign to keep its state stable, or deliberately share state across differently configured runs. Leave empty to let the actor derive a key automatically from the targets and filter settings.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return listings that have not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return listings that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned every tracked target.

## `ignoreFieldsForChanges` (type: `array`):

Extra field names that should NOT make a listing count as UPDATED, for example likeCount, shareCount or commentCount if you only care about price and availability. They are added to the fields that are always left out (comments, scrapedAt, \_enrichmentFailed, soldPrice, status, nwt, likesCount, commentsCount, thumbnailUrl, daysToSell, shippingCost). The fields stay in the output; they are just left out of the change check and out of changedFields. Used only when Incremental changes is on.

## `mcpConnectors` (type: `array`):

Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write or digest. Leave empty to skip; never changes the dataset output.

## `notionParentPageUrl` (type: `string`):

URL or id of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "mode": "search",
  "searchQueries": [
    "tote bag"
  ],
  "availability": "available",
  "shippingFilter": "all",
  "sortBy": "relevance",
  "listingInputs": [
    "https://poshmark.com/brand/Madewell",
    "https://poshmark.com/brand/Madewell-Women",
    "https://poshmark.com/search?query=tote%20bag&type=listings",
    "https://poshmark.com/search?query=tote&department=Women&availability=sold_out",
    "https://poshmark.com/category/Women-Bags",
    "https://poshmark.com/category/Women",
    "https://poshmark.com/category/Women-Dresses-Mini?condition=nwt",
    "https://poshmark.com/closet/poshmark",
    "https://poshmark.com/brand/Madewell?availability=sold_out&sort_by=added_desc",
    "https://poshmark.com/brand/Madewell?max_id=2",
    "https://poshmark.com/listing/Madewell-Cattail-Tiered-Midi-Dress-Red-6acbfd13b552236b28cafa0b",
    "https://poshmark.com/listing/6acbfd13b552236b28cafa0b"
  ],
  "urls": [
    "https://poshmark.com/brand/Madewell",
    "https://poshmark.com/brand/Madewell-Women",
    "https://poshmark.com/search?query=tote%20bag&type=listings",
    "https://poshmark.com/search?query=tote&department=Women&availability=sold_out",
    "https://poshmark.com/category/Women-Bags",
    "https://poshmark.com/category/Women",
    "https://poshmark.com/category/Women-Dresses-Mini?condition=nwt",
    "https://poshmark.com/closet/poshmark",
    "https://poshmark.com/brand/Madewell?availability=sold_out&sort_by=added_desc",
    "https://poshmark.com/brand/Madewell?max_id=2",
    "https://poshmark.com/listing/Madewell-Cattail-Tiered-Midi-Dress-Red-6acbfd13b552236b28cafa0b",
    "https://poshmark.com/listing/6acbfd13b552236b28cafa0b"
  ],
  "fetchDetails": false,
  "maxComments": 20,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "ignoreFieldsForChanges": [],
  "maxNotifyListings": 50
}
```

# Actor output Schema

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

No description

## `detail` (type: `string`):

No description

## `changes` (type: `string`):

No description

## `sellers` (type: `string`):

No description

## `summary` (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 = {
    "mode": "search",
    "searchQueries": [
        "tote bag"
    ],
    "availability": "available",
    "listingInputs": [
        "https://poshmark.com/brand/Madewell",
        "https://poshmark.com/brand/Madewell-Women",
        "https://poshmark.com/search?query=tote%20bag&type=listings",
        "https://poshmark.com/search?query=tote&department=Women&availability=sold_out",
        "https://poshmark.com/category/Women-Bags",
        "https://poshmark.com/category/Women",
        "https://poshmark.com/category/Women-Dresses-Mini?condition=nwt",
        "https://poshmark.com/closet/poshmark",
        "https://poshmark.com/brand/Madewell?availability=sold_out&sort_by=added_desc",
        "https://poshmark.com/brand/Madewell?max_id=2",
        "https://poshmark.com/listing/Madewell-Cattail-Tiered-Midi-Dress-Red-6acbfd13b552236b28cafa0b",
        "https://poshmark.com/listing/6acbfd13b552236b28cafa0b"
    ],
    "urls": [
        "https://poshmark.com/brand/Madewell",
        "https://poshmark.com/brand/Madewell-Women",
        "https://poshmark.com/search?query=tote%20bag&type=listings",
        "https://poshmark.com/search?query=tote&department=Women&availability=sold_out",
        "https://poshmark.com/category/Women-Bags",
        "https://poshmark.com/category/Women",
        "https://poshmark.com/category/Women-Dresses-Mini?condition=nwt",
        "https://poshmark.com/closet/poshmark",
        "https://poshmark.com/brand/Madewell?availability=sold_out&sort_by=added_desc",
        "https://poshmark.com/brand/Madewell?max_id=2",
        "https://poshmark.com/listing/Madewell-Cattail-Tiered-Midi-Dress-Red-6acbfd13b552236b28cafa0b",
        "https://poshmark.com/listing/6acbfd13b552236b28cafa0b"
    ],
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": true
    },
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "ignoreFieldsForChanges": [],
    "maxNotifyListings": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/poshmark-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 = {
    "mode": "search",
    "searchQueries": ["tote bag"],
    "availability": "available",
    "listingInputs": [
        "https://poshmark.com/brand/Madewell",
        "https://poshmark.com/brand/Madewell-Women",
        "https://poshmark.com/search?query=tote%20bag&type=listings",
        "https://poshmark.com/search?query=tote&department=Women&availability=sold_out",
        "https://poshmark.com/category/Women-Bags",
        "https://poshmark.com/category/Women",
        "https://poshmark.com/category/Women-Dresses-Mini?condition=nwt",
        "https://poshmark.com/closet/poshmark",
        "https://poshmark.com/brand/Madewell?availability=sold_out&sort_by=added_desc",
        "https://poshmark.com/brand/Madewell?max_id=2",
        "https://poshmark.com/listing/Madewell-Cattail-Tiered-Midi-Dress-Red-6acbfd13b552236b28cafa0b",
        "https://poshmark.com/listing/6acbfd13b552236b28cafa0b",
    ],
    "urls": [
        "https://poshmark.com/brand/Madewell",
        "https://poshmark.com/brand/Madewell-Women",
        "https://poshmark.com/search?query=tote%20bag&type=listings",
        "https://poshmark.com/search?query=tote&department=Women&availability=sold_out",
        "https://poshmark.com/category/Women-Bags",
        "https://poshmark.com/category/Women",
        "https://poshmark.com/category/Women-Dresses-Mini?condition=nwt",
        "https://poshmark.com/closet/poshmark",
        "https://poshmark.com/brand/Madewell?availability=sold_out&sort_by=added_desc",
        "https://poshmark.com/brand/Madewell?max_id=2",
        "https://poshmark.com/listing/Madewell-Cattail-Tiered-Midi-Dress-Red-6acbfd13b552236b28cafa0b",
        "https://poshmark.com/listing/6acbfd13b552236b28cafa0b",
    ],
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": True },
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "ignoreFieldsForChanges": [],
    "maxNotifyListings": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/poshmark-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 '{
  "mode": "search",
  "searchQueries": [
    "tote bag"
  ],
  "availability": "available",
  "listingInputs": [
    "https://poshmark.com/brand/Madewell",
    "https://poshmark.com/brand/Madewell-Women",
    "https://poshmark.com/search?query=tote%20bag&type=listings",
    "https://poshmark.com/search?query=tote&department=Women&availability=sold_out",
    "https://poshmark.com/category/Women-Bags",
    "https://poshmark.com/category/Women",
    "https://poshmark.com/category/Women-Dresses-Mini?condition=nwt",
    "https://poshmark.com/closet/poshmark",
    "https://poshmark.com/brand/Madewell?availability=sold_out&sort_by=added_desc",
    "https://poshmark.com/brand/Madewell?max_id=2",
    "https://poshmark.com/listing/Madewell-Cattail-Tiered-Midi-Dress-Red-6acbfd13b552236b28cafa0b",
    "https://poshmark.com/listing/6acbfd13b552236b28cafa0b"
  ],
  "urls": [
    "https://poshmark.com/brand/Madewell",
    "https://poshmark.com/brand/Madewell-Women",
    "https://poshmark.com/search?query=tote%20bag&type=listings",
    "https://poshmark.com/search?query=tote&department=Women&availability=sold_out",
    "https://poshmark.com/category/Women-Bags",
    "https://poshmark.com/category/Women",
    "https://poshmark.com/category/Women-Dresses-Mini?condition=nwt",
    "https://poshmark.com/closet/poshmark",
    "https://poshmark.com/brand/Madewell?availability=sold_out&sort_by=added_desc",
    "https://poshmark.com/brand/Madewell?max_id=2",
    "https://poshmark.com/listing/Madewell-Cattail-Tiered-Midi-Dress-Red-6acbfd13b552236b28cafa0b",
    "https://poshmark.com/listing/6acbfd13b552236b28cafa0b"
  ],
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "ignoreFieldsForChanges": [],
  "maxNotifyListings": 50
}' |
apify call abotapi/poshmark-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/poshmark-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/kIv3eRyHBlVaLqzj6/builds/GIpGUzQNk4o80Bgz1/openapi.json
