# 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)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## 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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Poshmark Scraper

Scrape [Poshmark](https://poshmark.com), the US social fashion-resale marketplace.

### Why This Scraper?

- Searches keywords, brands, categories, seller closets, and pasted links.
- Pulls available, sold, or all-availability listings with sold dates when available.
- Preserves listing prices, retail anchors, conditions, sizes, social counts, and media.
- Adds seller profile records when a closet is scraped.
- Supports bounded runs with a default `maxItems` value of 20.
- Supports resume and incremental monitoring for recurring searches.
- Incremental records can be labelled `NEW`, `UPDATED`, `REAPPEARED`, or `EXPIRED`.

### Data You Get

| Field | Description |
| --- | --- |
| `kind` | `listing` or `seller` record type. |
| `recordId` | Stable record identifier. |
| `listingId` | Poshmark listing identifier for listing records. |
| `url` | Public listing or seller URL. |
| `title` | Listing title. |
| `brand` | Listing brand when available. |
| `sellerUsername` | Seller handle. |
| `sellerName` | Seller display name. |
| `price` | Current or last listed price. |
| `originalPrice` | Retail price anchor when available. |
| `currency` | Currency code. |
| `size` | Normalized size. |
| `condition` | Normalized condition code. |
| `conditionLabel` | Human-readable condition. |
| `department` | Department such as Women, Men, or Home. |
| `category` | Listing category. |
| `description` | Listing description. |
| `availability` | Available or sold state. |
| `soldAt` | Sold timestamp when available. |
| `likeCount` | Listing likes. |
| `pictureUrls` | Listing image URLs. |
| `followers` | Seller follower count on seller records. |

### How to Use

The default mode is search. Add any combination of keyword searches, brands, or seller closets.
For optional exports, configure the `## Send results into your apps (MCP connectors)` inputs.

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

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

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

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

### Input Parameters

| Input | Description |
| --- | --- |
| `mode` | `search` for keywords, brands, and closets, or `url` for pasted links. |
| `searchQueries` | Keyword searches in search mode. |
| `brands` | Brand names or brand-page paths. |
| `closets` | Seller usernames or closet links. |
| `availability` | `available`, `sold_out`, or `all`. |
| `department` | Optional department filter. |
| `condition` | Optional condition filter: `nwt`, `uln`, `ug`, or `uf`. |
| `listingInputs` | Listing, closet, brand, category, or search links in URL mode. |
| `urls` | Alias for `listingInputs`. |
| `fetchDetails` | Read listing pages for additional seller and shipping fields. |
| `maxItems` | Result cap; defaults to 20. Set to 0 for no limit. |
| `resumeFromRunId` | Continue an interrupted run without returning prior records. |
| `incrementalMode` | Return only changes on recurring runs. |
| `stateKey` | Optional name for shared incremental state. |
| `emitUnchanged` | Include unchanged incremental records. |
| `emitExpired` | Include records no longer found in a completed scan. |
| `mcpConnectors` | Optional connector IDs for exporting results. |
| `notionParentPageUrl` | Parent page for Notion exports. |
| `maxNotifyListings` | Connector export cap; defaults to 50. |
| `proxyConfiguration` | Apify Proxy configuration. |

### Output Example

```json
{
  "kind": "listing",
  "recordId": "e0000000000000000000000a",
  "listingId": "e0000000000000000000000a",
  "url": "https://poshmark.com/listing/Sample-Coat-e0000000000000000000000a",
  "title": "Sample Brand Co Wool Coat",
  "brand": "Sample Brand Co",
  "sellerUsername": "sample_seller",
  "size": "M",
  "condition": "nwt",
  "conditionLabel": "New With Tags",
  "price": 40.0,
  "originalPrice": 120.0,
  "currency": "USD",
  "availability": "sold",
  "soldAt": "2026-01-01T10:00:00-07:00",
  "likeCount": 12,
  "pictureUrls": ["https://images.example.invalid/sample.jpg"]
}
```

### Plan Requirement

Use the actor only for public Poshmark data. Respect Poshmark's terms and applicable law. Detail enrichment reads one page per listing and may add a small per-listing surcharge; leave it off unless those fields are needed.

# 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.

## `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.

## `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).

## `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.

## `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. 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.

## `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.

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

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

## Actor input object example

```json
{
  "mode": "search",
  "searchQueries": [
    "tote bag"
  ],
  "availability": "available",
  "listingInputs": [
    "https://poshmark.com/brand/Madewell"
  ],
  "urls": [
    "https://poshmark.com/brand/Madewell"
  ],
  "fetchDetails": false,
  "maxItems": 20,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "maxNotifyListings": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `overview` (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"
    ],
    "urls": [
        "https://poshmark.com/brand/Madewell"
    ],
    "maxItems": 20,
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false,
    "maxNotifyListings": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// 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"],
    "urls": ["https://poshmark.com/brand/Madewell"],
    "maxItems": 20,
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
    "maxNotifyListings": 50,
    "proxyConfiguration": { "useApifyProxy": True },
}

# 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"
  ],
  "urls": [
    "https://poshmark.com/brand/Madewell"
  ],
  "maxItems": 20,
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "maxNotifyListings": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
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/T3Yq6msKYx3XOWu2v/openapi.json
