# Poshmark API scraper — search for-sale and SOLD resale listings on poshmark.com (US) and poshmark.ca (Canada), read a full listing with shipping and bundle discounts, browse a seller's closet and profile, similar listings and brand suggestions. No account, no browser.

> Search Poshmark listings by keyword, or browse a department, category or brand, in the US or Canada. Every row: listing id and url, title, brand, current price with the seller's stated original price, price-drop percentage, sold or available with the sold date, condition, size with per-size quantities, department and category, colours, seller-paid shipping flag, likes, comments and shares, the seller's username and closet url. Filter by department, category, brand, size, colour, condition, price range, shipping discount and availability (set availability=sold for sold comparables); sort by relevance, newest, price, likes or price drops; page with `next_cursor`.
> ReefAPI engine `poshmark` · 6 endpoints · clean JSON, no scraping or browsers to manage.

## How to call
- **Endpoint:** `POST https://api.reefapi.com/poshmark/v1/<action>` with a JSON body.
- **Auth:** header `x-api-key: <YOUR_REEFAPI_KEY>` — create one free (1,000 credits, no card): https://reefapi.com/signup
- **Response (every call):** `{ ok: boolean, data: ..., meta: { record_count, credits, ... }, error: { code, message } }` — branch on `ok`. Failed calls are free except verified SHEIN NOT_FOUND on product/detail and price (4 credits).
- **One key + one shared credit pool** across every ReefAPI API. Per-call credits are listed on each endpoint below.
- **Use it from an AI agent (MCP):** connect `https://api.reefapi.com/mcp` (remote streamable-http, `Authorization: Bearer <key>`) and your assistant can call these actions directly.

## Endpoints

### POST /poshmark/v1/search — 1 credit
Search Poshmark listings by keyword, or browse a department, category or brand, in the US or Canada. Every row: listing id and url, title, brand, current price with the seller's stated original price, price-drop percentage, sold or available with the sold date, condition, size with per-size quantities, department and category, colours, seller-paid shipping flag, likes, comments and shares, the seller's username and closet url. Filter by department, category, brand, size, colour, condition, price range, shipping discount and availability (set availability=sold for sold comparables); sort by relevance, newest, price, likes or price drops; page with `next_cursor`.

**Parameters:**
- `query` (string, optional) — Keywords. Optional when a department or brand is given (browse).
- `include_similar` (boolean, optional, default false) — When a keyword has no exact matches Poshmark fills the page with 'similar' listings. By default those are left out and counted in `similar_results_available`; true returns them, each marked `match: similar`.
- `country` (enum, optional, default "us") — Poshmark marketplace. Prices come back in that marketplace's currency. Poshmark Australia and India have closed and return MARKET_UNAVAILABLE. [one of: us, ca]
- `department` (enum, optional) — Poshmark department. [one of: Women, Men, Kids, Home, Pets, Electronics]
- `category` (string, optional) — Category inside the department, e.g. Women → Dresses, Jackets_&_Coats; Men → Shoes; Home → Kitchen; Electronics → Headphones. Needs `department`. Spaces or underscores both work; an unknown category is rejected with the valid list.
- `brand` (string, optional) — Brand name as Poshmark lists it (comma-separate up to 10). Matching is case-insensitive. `suggest` returns exact brand names.
- `size` (string, optional) — Size label(s) as sellers enter them, comma-separated: M, XL, 8, 10.5, OS (one size), 32x30.
- `color` (string, optional) — Colour(s), comma-separated: Red, Pink, Orange, Yellow, Green, Blue, Purple, Gold, Silver, Black, Gray, White, Cream, Brown, Tan.
- `condition` (string, optional) — Condition(s), comma-separated: new_with_tags, not_new_with_tags, like_new, good, fair, boutique (new items from Poshmark boutique sellers).
- `availability` (enum, optional, default "available") — For-sale listings, or sold ones. A sold listing's price is its last listed price — Poshmark does not publish the amount an accepted offer closed at. [one of: available, sold]
- `price_min` (number, optional) — Lowest listed price, in the marketplace currency.
- `price_max` (number, optional) — Highest listed price, in the marketplace currency.
- `shipping` (enum, optional) — Only listings whose seller pays part or all of the shipping. [one of: free, discounted]
- `sort` (enum, optional, default "relevance") — Order of results. Unknown values are rejected, not ignored. [one of: relevance, newest, price_asc, price_desc, most_liked, price_drop]
- `limit` (integer, optional, default 48) — Listings per call, 1-100 (Poshmark's own page is 48).
- `cursor` (string, optional) — Continue a previous call: pass back its `next_cursor`. `next_cursor: null` is the end.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** results[]{listing_id, title, url, brand (as listed), brand_canonical, brand_id, price (number — current listed price), currency, original_price (the seller's stated retail price, null when not stated), discount_from_original_percent, first_listed_price, price_drop_percent, status (available|sold_out|not_for_sale|reserved…), is_sold, sold_at, condition (new_with_tags|not_new_with_tags|boutique|wholesale|like_new|good|fair|null), condition_code, size, size_code, size_system, sizes[]{size, size_code, size_system, quantity_available, quantity_sold}, quantity_available, multi_item, department, category, subcategories[], colors[], style_tags[], shipping_discount (free|discounted|null), image, image_count, like_count, comment_count, share_count, seller{id, username, url, picture}, listed_at (first published), available_since (when it last became available — what sort=newest follows), publish_count, updated_at, origin_country, available_in[], match (similar|null)}, count, next_cursor, total_results (exact matches, capped at 5000), total_results_capped, similar_results_available, similar_rows_dropped, filters{}, country, query

**Example request body:**
```json
{
  "query": "nike"
}
```

### POST /poshmark/v1/product/detail — 1 credit
One Poshmark listing in full, by listing id or URL: title, description, brand, current price, the seller's stated original price, first listed price and price-drop percentage, availability and sold date, condition, size and per-size quantities, department / category / subcategory path, colours, style tags, every photo, the shipping price with any seller discount (free or reduced), the seller's bundle discount, like / comment / share counts and the public comments, and the seller's username and closet url.

**Parameters:**
- `listing_id` (string, required) — Poshmark listing id (24 characters, the end of a listing URL) or the full listing URL. Every search row returns it as `listing_id`.
- `country` (enum, optional, default "us") — Poshmark marketplace. Prices come back in that marketplace's currency. Poshmark Australia and India have closed and return MARKET_UNAVAILABLE. [one of: us, ca]
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** listing{listing_id, title, url, brand (as listed), brand_canonical, brand_id, price (number — current listed price), currency, original_price (the seller's stated retail price, null when not stated), discount_from_original_percent, first_listed_price, price_drop_percent, status (available|sold_out|not_for_sale|reserved…), is_sold, sold_at, condition (new_with_tags|not_new_with_tags|boutique|wholesale|like_new|good|fair|null), condition_code, size, size_code, size_system, sizes[]{size, size_code, size_system, quantity_available, quantity_sold}, quantity_available, multi_item, department, category, subcategories[], colors[], style_tags[], shipping_discount (free|discounted|null), image, image_count, like_count, comment_count, share_count, seller{id, username, url, picture}, listed_at (first published), available_since (when it last became available — what sort=newest follows), publish_count, updated_at, origin_country, available_in[], match (similar|null), description, images[], video_count, shipping{price (0 = free), price_before_discount, currency, discount_type, label}, bundle_discount{percent, min_items, label}, notices[], active_offer_count, comments[]{comment_id, username, text, created_at}, category_path[], availability_changed_at}

### POST /poshmark/v1/product/similar — 1 credit
The listings Poshmark shows as similar to one listing (usually 16), with the same row fields as `search`.

**Parameters:**
- `listing_id` (string, required) — Poshmark listing id (24 characters, the end of a listing URL) or the full listing URL. Every search row returns it as `listing_id`.
- `country` (enum, optional, default "us") — Poshmark marketplace. Prices come back in that marketplace's currency. Poshmark Australia and India have closed and return MARKET_UNAVAILABLE. [one of: us, ca]
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** listing_id, results[]{listing_id, title, url, brand (as listed), brand_canonical, brand_id, price (number — current listed price), currency, original_price (the seller's stated retail price, null when not stated), discount_from_original_percent, first_listed_price, price_drop_percent, status (available|sold_out|not_for_sale|reserved…), is_sold, sold_at, condition (new_with_tags|not_new_with_tags|boutique|wholesale|like_new|good|fair|null), condition_code, size, size_code, size_system, sizes[]{size, size_code, size_system, quantity_available, quantity_sold}, quantity_available, multi_item, department, category, subcategories[], colors[], style_tags[], shipping_discount (free|discounted|null), image, image_count, like_count, comment_count, share_count, seller{id, username, url, picture}, listed_at (first published), available_since (when it last became available — what sort=newest follows), publish_count, updated_at, origin_country, available_in[], match (similar|null)}, count, country

### POST /poshmark/v1/seller/listings — 1 credit
One seller's closet: their for-sale or sold listings with the same row fields and filters as `search` (department, category, brand, size, colour, condition, price, shipping), sorted and paged. Use availability=sold for a seller's sales history.

**Parameters:**
- `seller` (string, required) — Seller username (the closet name in poshmark.com/closet/<username>), the seller id (`seller.id` on every listing), or the closet URL.
- `country` (enum, optional, default "us") — Poshmark marketplace. Prices come back in that marketplace's currency. Poshmark Australia and India have closed and return MARKET_UNAVAILABLE. [one of: us, ca]
- `department` (enum, optional) — Poshmark department. [one of: Women, Men, Kids, Home, Pets, Electronics]
- `category` (string, optional) — Category inside the department, e.g. Women → Dresses, Jackets_&_Coats; Men → Shoes; Home → Kitchen; Electronics → Headphones. Needs `department`. Spaces or underscores both work; an unknown category is rejected with the valid list.
- `brand` (string, optional) — Brand name as Poshmark lists it (comma-separate up to 10). Matching is case-insensitive. `suggest` returns exact brand names.
- `size` (string, optional) — Size label(s) as sellers enter them, comma-separated: M, XL, 8, 10.5, OS (one size), 32x30.
- `color` (string, optional) — Colour(s), comma-separated: Red, Pink, Orange, Yellow, Green, Blue, Purple, Gold, Silver, Black, Gray, White, Cream, Brown, Tan.
- `condition` (string, optional) — Condition(s), comma-separated: new_with_tags, not_new_with_tags, like_new, good, fair, boutique (new items from Poshmark boutique sellers).
- `availability` (enum, optional, default "available") — For-sale listings, or sold ones. A sold listing's price is its last listed price — Poshmark does not publish the amount an accepted offer closed at. [one of: available, sold]
- `price_min` (number, optional) — Lowest listed price, in the marketplace currency.
- `price_max` (number, optional) — Highest listed price, in the marketplace currency.
- `shipping` (enum, optional) — Only listings whose seller pays part or all of the shipping. [one of: free, discounted]
- `sort` (enum, optional, default "relevance") — Order of results. Unknown values are rejected, not ignored. [one of: relevance, newest, price_asc, price_desc, most_liked, price_drop]
- `limit` (integer, optional, default 48) — Listings per call, 1-100 (Poshmark's own page is 48).
- `cursor` (string, optional) — Continue a previous call: pass back its `next_cursor`. `next_cursor: null` is the end.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** results[]{listing_id, title, url, brand (as listed), brand_canonical, brand_id, price (number — current listed price), currency, original_price (the seller's stated retail price, null when not stated), discount_from_original_percent, first_listed_price, price_drop_percent, status (available|sold_out|not_for_sale|reserved…), is_sold, sold_at, condition (new_with_tags|not_new_with_tags|boutique|wholesale|like_new|good|fair|null), condition_code, size, size_code, size_system, sizes[]{size, size_code, size_system, quantity_available, quantity_sold}, quantity_available, multi_item, department, category, subcategories[], colors[], style_tags[], shipping_discount (free|discounted|null), image, image_count, like_count, comment_count, share_count, seller{id, username, url, picture}, listed_at (first published), available_since (when it last became available — what sort=newest follows), publish_count, updated_at, origin_country, available_in[], match (similar|null)}, count, next_cursor, total_results (exact matches, capped at 5000), total_results_capped, similar_results_available, similar_rows_dropped, filters{}, country, seller

### POST /poshmark/v1/seller/profile — 1 credit
A seller's public Poshmark profile by username, id or closet URL: username, picture, bio, join date, last active date, number of listings (resale, boutique, wholesale), followers and following, items sold as Poshmark displays it, orders shipped and whether the closet is on vacation hold.

**Parameters:**
- `seller` (string, required) — Seller username (the closet name in poshmark.com/closet/<username>), the seller id (`seller.id` on every listing), or the closet URL.
- `country` (enum, optional, default "us") — Poshmark marketplace. Prices come back in that marketplace's currency. Poshmark Australia and India have closed and return MARKET_UNAVAILABLE. [one of: us, ca]
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** seller{id, username, display_handle, url, picture, bio, joined_at, status, home_country, last_active_date, listings_count, resale_listings, boutique_listings, wholesale_listings, followers, following, items_sold_display (Poshmark's own rounded label, e.g. '30+'), orders_shipped, vacation_hold}

### POST /poshmark/v1/suggest — 1 credit
Poshmark's brand suggestions for a partial brand name — the exact names the `brand` filter matches.

**Parameters:**
- `query` (string, required) — The start of a brand name.
- `country` (enum, optional, default "us") — Poshmark marketplace. Prices come back in that marketplace's currency. Poshmark Australia and India have closed and return MARKET_UNAVAILABLE. [one of: us, ca]
- `limit` (integer, optional, default 10) — Maximum suggestions, 1-20.
- `max_rotations` (integer, optional, default 3) — Advanced: how many times to retry a difficult request (1-5).

**Returns:** suggestions[]{type (brand), id, name}, count, query, country

**Example request body:**
```json
{
  "query": "nike"
}
```

## More
- Try it live, no code: https://reefapi.com/playground?engine=poshmark
- Human docs page: https://reefapi.com/docs/poshmark
- Overview page: https://reefapi.com/poshmark-api
- Every ReefAPI API in one file (for your AI): https://reefapi.com/llms-full.txt
