Chairish Scraper: New Listing & Price Drop Alerts avatar

Chairish Scraper: New Listing & Price Drop Alerts

Pricing

from $1.50 / 1,000 listing returneds

Go to Apify Store
Chairish Scraper: New Listing & Price Drop Alerts

Chairish Scraper: New Listing & Price Drop Alerts

Chairish scraper by category: US vintage furniture and decor with price, markdown flag and dealer info, plus new-listing and price-drop alerts. No login required. Pay per listing; misses and quiet runs are free.

Pricing

from $1.50 / 1,000 listing returneds

Rating

0.0

(0)

Developer

Adrian Voss

Adrian Voss

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Share

Watch a search, get only what's new. New listings and price drops since your last run, charged per new row, free on quiet days. Schedule it hourly and send it to Discord, Slack, Google Sheets or n8n.

This actor reads Chairish, the US vintage furniture and decor marketplace, by category: give it a keyword like "chairs" or "wall mirrors", or paste a chairish.com/collection/... link, and get one row per listing with the title, price, Chairish's own category path, its newly-made/vintage flag, and the link. Turn on monitoring and each run returns only the listings that appeared, or got cheaper, since the previous run — including a listing Chairish itself just marked down.

Who it's for

  • Dealers and sourcing agents hunting vintage pieces on Chairish who lose good finds to whoever refreshes the page fastest. A watchlist on "chairs" or "chaise lounge", run every hour, puts new listings in your Discord or Telegram without keeping a tab open.
  • Interior designers researching what a category or period piece genuinely costs on Chairish right now.
  • Resellers watching for Chairish's own markdowns — this actor treats a listing going on sale as a price-drop alert, not just a price falling below what this monitor last saw.
  • Bot and workflow builders who want a stable JSON row per listing instead of maintaining their own scraper.

Why this one

  • Category-first search, honestly. Chairish's own robots.txt disallows /search, so this actor never uses it — and it only maps keywords to the Chairish collections this build actually confirmed render a real product grid server-side (chairs, wall mirrors, chaise lounge, runner rugs, bar stools, and a handful more). Most of Chairish's own category names for common furniture nouns (mirrors, sofas, tables, dining chairs...) turned out to be "hub" pages with an empty, JavaScript-only product grid; rather than silently return zero rows for those, this actor rejects them up front with a clear message. A pasted chairish.com/collection/... link works for any leaf collection, including ones this build didn't test.
  • Monitoring built in, not bolted on. deltaMode remembers what each watchlist has seen. New listings and price drops (with your own minimum drop %) come back; everything else is removed before billing. A quiet run returns one summary row and costs only the start fee.
  • Chairish's own markdown flag counts too. A listing that goes on sale is a price drop even the first time this monitor sees it — see "Monitoring" below.
  • No login required. Chairish's collection pages are plain server-rendered HTML — no CAPTCHA, and a residential IP reads them with no challenge at all.

What you get

By default each listing is its own row. Every row also repeats the search it came from.

FieldWhat it is
listingId, url, titleChairish's listing ID, the listing link and its title
price, currencyThe price in US dollars
categoryChairish's own full category path (e.g. "Furniture/Seating/Dining Chairs")
isNewlyMade, conditionChairish's own newly-made flag, and the same thing as New / Vintage/Antique — not a graded condition (see FAQ)
isDiscounted, discountPctChairish's own markdown flag and percentage
isPurchasableWhether Chairish currently shows the listing as purchasable
imageUrlLink to the main photo (links only, nothing is downloaded)
sellerType, sellerHashAlways dealer (see FAQ), and an anonymous 16-character dealer hash
isNew, changeType, firstSeenAtMonitoring: new, price-drop or seen, and when this watchlist first saw it
previousPrice, priceDropPctMonitoring: the price last seen and the drop in %, on price-drop rows
searchQuery, listingCount, truncatedThe search summary
newCount, priceDropCount, monitorStatusMonitoring summary

Not in this actor, because Chairish's own listing cards don't carry them (confirmed on the sampled cards): a posting date or a total-matches count. totalAvailable is always empty.

Monitoring: new listings and price drops

The recipe most buyers use:

  1. Put your search in searches (a Chairish category keyword, or paste a collection link), and turn on Only return listings that are new, or cheaper, since the last run (deltaMode).
  2. Optionally turn on Seed silently so the first run remembers today's listings without sending them all to your webhook.
  3. Save it as a Task and add an hourly Schedule in Apify.
  4. Add a webhook or integration on the Task for Run succeeded: Discord or Slack webhook, Telegram bot via n8n or Make, a Google Sheets append, or an HTTP call to your own bot.
{
"searches": ["chairs"],
"maxPrice": 2000,
"deltaMode": true,
"skipFirstRun": true,
"alertOnNew": true,
"alertOnPriceDrop": true,
"minPriceDropPct": 10
}

How it decides:

  • New means this watchlist has never returned that listing ID before.
  • Price drop means the price is at least minPriceDropPct below the price last seen. Because this actor tracks the CURRENT price (already net of any markdown), a listing that goes on sale is naturally a price drop from the second run on.
  • Chairish's own markdown, even on a first sighting. A listing your watchlist has never seen before, but which Chairish already shows as marked down, is delivered as a price-drop alert too — even if "Alert on new listings" is off — so a buyer watching only for markdowns doesn't miss one just because it's also new to the watchlist.
  • Unchanged listings are removed before you are billed. A run with nothing new returns one summary row with monitorStatus: NO_NEW_ROWS, listingCount: 0, and costs only the start fee.
  • Each watchlist remembers up to 5,000 listings, oldest forgotten first.

Limitations. Chairish's collection pages expose no total-matches count anywhere in the static HTML, so totalAvailable is always empty and truncated is a best-effort signal based on whether the last page fetched was still full. A run only sees the newest maxListingsPerSearch listings; a listing that drops in price after it slides out of that window is not seen again. This actor defaults its proxy to Residential rather than Datacenter — Chairish answers Apify's shared datacenter IP range with an HTTP 418 block, even though it serves a plain, un-challenged page to an ordinary residential IP.

Price

  • Listings: $3 per 1,000 listings returned, plus a $0.00005 start fee per run.
  • A monitoring run with nothing new costs the start fee only. A search that returns nothing is never billed.

How to use

  1. In the Apify Console. Open the actor page and click Start — the searches field is already pre-filled with a working example. Results land in the run's dataset as soon as each item is found.
  2. Via the API. Call it directly with a POST request — no Console needed once you have an API token:
    curl "https://api.apify.com/v2/acts/accountable_eel~chairish-listing-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
    -X POST \
    -H "Content-Type: application/json" \
    -d '{"searches":["chairs"]}'
  3. On a schedule. Save this actor as an Apify Task with the input you want, then add a Schedule (hourly, daily, weekly) so it runs on its own — no server of your own required.

Tips:

  • includeKeywords/excludeKeywords match the title and Chairish's own category path before billing, so a word you don't want never costs you a row.
  • minPrice/maxPrice are applied after fetching — Chairish has no price-filter URL parameter this build could find, so these are honoured client-side rather than dropped silently.
  • If your keyword doesn't match, paste the real chairish.com/collection/... link instead — the actor's error message tells you when this happens.

Input

{
"searches": [
"chairs"
]
}

One search per line — a keyword matching a Chairish category (e.g. "chairs", "wall mirrors", "chaise lounge") or a pasted chairish.com/collection/... link. Chairish's search page is off-limits by its own robots.txt, so a keyword must resolve to one of Chairish's own collections. No login required. Accepted formats: chairs, wall mirrors, https://www.chairish.com/collection/decor, https://www.chairish.com/collection/us-vintage.

Sample output

queryfoundstatussearchQuerylistingCounttruncatednewCountpriceDropCountmonitorStatuslistingslistingIdtitlepricecurrencycategoryisNewlyMadeconditionisDiscounteddiscountPctisPurchasableimageUrlsellerTypesellerHashchangeTypeisNewpreviousPricepriceDropPctfirstSeenAturlscrapedAt
chairstrueOK<monitoring status (quiet / seeded runs)><all listings found (full list)> <price (usd)><chairish's own category path><newly made (vs. vintage/antique)><new or vintage/antique, from chairish's own flag><chairish's own markdown flag><discount % (chairish's own)><always "dealer" — see readme><new / price-drop / seen><is this listing new?><price drop % (this monitor)>1970-01-01T00:00:00.000Z

A real row from a chairs run (2026-09-22), trimmed:

{
"searchQuery": "chairs",
"listingCount": 5,
"listingId": "35487167",
"url": "https://www.chairish.com/product/35487167/antique-viennese-fan-chairs-in-walnut-veneer-with-lemon-band-inlays-austria-1830-set-of-6",
"title": "Antique Viennese Fan Chairs in Walnut Veneer with Lemon Band Inlays, Austria, 1830, Set of 6",
"price": 17971,
"currency": "USD",
"category": "Furniture/Seating/Dining Chairs",
"isNewlyMade": false,
"condition": "Vintage/Antique",
"isDiscounted": false,
"sellerType": "dealer",
"sellerHash": "3f7c1a9e0d2b5648"
}

Use it from Clay, n8n, Make, or an AI agent

This actor runs synchronously over plain HTTP — call it directly from a script, a workflow tool, or an AI agent, no Apify Console needed once you have an API token.

curl "https://api.apify.com/v2/acts/accountable_eel~chairish-listing-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
-X POST \
-H "Content-Type: application/json" \
-d '{"searches":["chairs"]}'

n8n. Add an HTTP Request node: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~chairish-listing-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body Content Type JSON, JSON Body {"searches":["chairs"]} (swap in an expression from an earlier node for a real value).

Clay. Add an "HTTP API" column: Method POST, URL https://api.apify.com/v2/acts/accountable_eel~chairish-listing-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>, Body {"searches":["{{search}}"]}, mapping the row's search into the searches array.

MCP. In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "Chairish Scraper: Vintage Furniture Price Alerts" — the agent will find and run this actor.

Discord or Slack alerts without code. Schedule the monitoring Task hourly, then add an integration on the Task: in n8n or Make, trigger on "Apify: run succeeded", read the run's dataset, skip rows where listingCount is 0, and post title, price, category and url to a Discord or Slack webhook. Google Sheets users can append the same rows for a running price log.

vs. alternatives

What it costsWhat you getTrade-off
This actor$3 per 1,000 listings, quiet monitoring runs freeCategory search mapped to Chairish's real collections, Chairish's own markdown flag treated as a price-drop signal, built-in new-listing and price-drop monitoringNo free-text search (robots.txt blocks it), no posting date or total-matches count
Checking Chairish by handFree, plus your timeFull controlDoesn't scale past a handful of searches and misses whatever appears between visits

Data & privacy

Data & privacy. This actor reads public listing pages that anyone can see without logging in. It doesn't log in, solve CAPTCHAs or reveal hidden contact details. Chairish's own listing cards expose no seller name, only an opaque dealer code; this actor hashes even that before it reaches the output. Not affiliated with Chairish.

FAQ

Is this allowed? It collects the same public listing data your browser shows, for the categories you choose. It's built for monitoring a category, not for copying the marketplace. Check that your use fits Chairish's terms and your local law — note that this actor deliberately never uses Chairish's /search page, which its own robots.txt disallows.

Why does my keyword not work? Chairish's search page is off-limits by its own robots.txt, so this actor only reads its category ("collection") pages — and only the ones that are genuine, server-rendered listing grids. A keyword must resolve to a real, working Chairish collection ("chairs", "wall mirrors", "chaise lounge", "runner rugs", "bar stools"...). Many other real Chairish category names for common furniture nouns (sofas, tables, dining chairs, most plain furniture nouns) are "hub" pages: real, valid links whose product grid Chairish itself only fills in with client-side JavaScript, which this actor doesn't run. Rather than silently return zero rows for those, this actor rejects them up front with a clear message. For anything else, paste the real chairish.com/collection/... link — if it turns out to be a hub page too, the run comes back with a clear "no listings" result rather than fabricated data.

Why is condition only "New" or "Vintage/Antique"? That's the only distinction Chairish's own listing cards expose — a binary newly-made flag, not a graded condition (like "excellent"/"good"/"fair"). It's reported as-is, not padded out with a grade Chairish doesn't provide.

Why is sellerType always "dealer"? Every Chairish listing card sampled during this build carried a dealer code and none exposed a private-seller flag — Chairish is a consignment-dealer marketplace, not a peer-to-peer one. The field is kept (rather than removed) so the anonymous sellerHash still has a labeled counterpart.

Why did my monitoring run return nothing? Nothing new or cheaper appeared since the last run. You get one row with

monitorStatus: NO_NEW_ROWS
and are charged only the start fee. On the very first run with "Seed silently" on, the status is SEEDED.

What do I need to set up? Nothing. No Chairish account, no cookies, no proxy settings.

Can an AI agent call this? Yes, through the Apify MCP server or the API call shown above. Ask for "Chairish Scraper: New Listing & Price Drop Alerts".