# Pamono Scraper: New Listing & Price Drop Alerts (`accountable_eel/pamono-listing-lookup`) Actor

Pamono scraper by keyword: design and vintage furniture from Pamono's EU/US marketplace with price, sale flag and designer info, plus new-listing and price-drop alerts. No login required. Pay per listing; misses and quiet runs are free.

- **URL**: https://apify.com/accountable\_eel/pamono-listing-lookup.md
- **Developed by:** [Adrian Voss](https://apify.com/accountable_eel) (community)
- **Categories:** E-commerce, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 listing returneds

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

## Pamono Scraper: New Listing & Price Drop Alerts

**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 searches Pamono, a European/US design and vintage-furniture marketplace, the way you
would in your browser: type a keyword or paste a category link, and get one row per listing with
the title, price, designer (when the title names one), the main photo 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 Pamono itself just put on sale.

### Who it's for

- **Dealers and sourcing agents** hunting mid-century and design pieces on Pamono who lose good
  finds to whoever refreshes the page fastest. A watchlist on "teak armchair" or "art deco mirror",
  run every hour, puts new listings in your Discord or Telegram without keeping a tab open.
- **Interior designers** researching what a designer, style or period piece genuinely costs on
  Pamono right now.
- **Resellers** watching for Pamono'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

- **Free-text keyword search**, not a fixed category list. Pamono's own homepage advertises a
  `catalogsearch` route for its search box; this actor uses the same one, so a keyword search
  covers everything a category browse would miss. A pasted `pamono.com/<category>` or
  `pamono.com/catalogsearch/...` link also works.
- **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.
- **Pamono's own sale 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, no anti-bot dance.** Pamono's category and search pages are plain server-rendered
  HTML with no CAPTCHA or challenge observed during this build.

### What you get

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

| Field | What it is |
|---|---|
| `listingId`, `url`, `title` | Pamono's listing ID, the listing link and its title |
| `price`, `currency` | The price, and the currency Pamono served on this run (see "Currency" below) |
| `regularPrice`, `isDiscounted`, `discountPct` | Pamono's own sale price vs. regular price, and the computed discount % |
| `designer`, `era` | Best-effort, parsed from the title's own "by \<designer>, \<decade>" convention — null when a title doesn't follow it |
| `imageUrl` | Link to the main photo (links only, nothing is downloaded) |
| `isSold` | True when Pamono shows the listing as sold out instead of a price |
| `isNew`, `changeType`, `firstSeenAt` | Monitoring: `new`, `price-drop` or `seen`, and when this watchlist first saw it |
| `previousPrice`, `priceDropPct` | Monitoring: the price last seen and the drop in %, on price-drop rows |
| `searchQuery`, `listingCount`, `truncated` | The search summary |
| `newCount`, `priceDropCount`, `monitorStatus` | Monitoring summary |

Not in this actor, because Pamono's own listing cards don't carry them (confirmed on ~290 sampled
cards across category and search pages): a posting date, seller identity of any kind, a condition
grade, or a total-matches count. `totalAvailable` is always empty — see "Limitations" below.

**Currency.** Pamono formats prices in the currency it decides for the request, and this build
found no reliable way to force one: a request from a Hungarian IP was still served in US dollars,
with no currency cookie, query parameter or selector anywhere in the page. This actor records
whichever currency symbol Pamono actually printed on each run's prices, rather than assuming one.

### Monitoring: new listings and price drops

The recipe most buyers use:

1. Put your search in `searches` (a keyword, or paste a Pamono category or search 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.

```json
{
  "searches": ["teak armchair"],
  "maxPrice": 1500,
  "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 SALE price (not the regular price) as a listing's price, a listing that
  goes on sale is naturally a price drop from the second run on.
- **Pamono's own discount, even on a first sighting.** A listing your watchlist has never seen
  before, but which Pamono already shows as discounted, 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.** Pamono's category and search pages expose no total-matches count anywhere in the
page (checked the page's only JSON-LD block — a bare `WebSite` search-action node, nothing else),
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.

### 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:
   ```bash
   curl "https://api.apify.com/v2/acts/accountable_eel~pamono-listing-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"searches":["teak armchair"]}'
   ```
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 the parsed designer name before billing,
  so a maker or word you don't want never costs you a row.
- `minPrice`/`maxPrice` are applied after fetching — Pamono has no price-filter URL parameter this
  build could find, so these are honoured client-side rather than dropped silently.

### Input

```json
{
  "searches": [
    "teak armchair"
  ]
}
```

One search per line — any keyword (e.g. "teak armchair", "art deco mirror") or a pasted pamono.com category or search link. No login required. Accepted formats: teak armchair, art deco mirror, https://www.pamono.com/armchairs, https://www.pamono.com/catalogsearch/result/?q=chaise+lounge.

### Sample output

| query | found | status | searchQuery | listingCount | truncated | newCount | priceDropCount | monitorStatus | listings | listingId | title | price | currency | regularPrice | isDiscounted | discountPct | designer | era | imageUrl | isSold | changeType | isNew | previousPrice | priceDropPct | firstSeenAt | url | scrapedAt |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| teak armchair | true | OK | <search> | <listings returned> | <more results were available> | <new listings this run> | <price drops this run> | \<monitoring status (quiet / seeded runs)> | \<all listings found (full list)> | <pamono listing id> | <title> | <price> | \<currency (as served this run — see readme)> | \<regular price, on sale items only> | \<pamono's own sale flag> | \<discount % (computed from price vs regular price)> | \<designer, parsed from the title when named> | \<decade, parsed from the title when named> | <image> | <sold out> | \<new / price-drop / seen> | \<is this listing new?> | <previous price seen by this monitor> | \<price drop % (this monitor)> | <first seen on a run> | <listing link> | 1970-01-01T00:00:00.000Z |

A real row from a `teak armchair` run (2026-09-22), trimmed:

```json
{
  "searchQuery": "teak armchair",
  "listingCount": 5,
  "listingId": "MZB-2163403",
  "url": "https://www.pamono.com/danish-teak-lounge-chair-1",
  "title": "Danish Teak Lounge Chair",
  "price": 992,
  "currency": "USD",
  "isDiscounted": false,
  "designer": null,
  "imageUrl": "https://cdn20.pamono.com/p/m/2/1/2163403_p41l7o40bq/danish-teak-lounge-chair.png",
  "isSold": false
}
```

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

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

**n8n.** Add an HTTP Request node: Method `POST`, URL `https://api.apify.com/v2/acts/accountable_eel~pamono-listing-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, Body Content Type `JSON`, JSON Body `{"searches":["teak armchair"]}` (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~pamono-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 "Pamono Scraper: Design 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`, `designer` 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 costs | What you get | Trade-off |
|---|---|---|---|
| **This actor** | $3 per 1,000 listings, quiet monitoring runs free | Free-text keyword search, Pamono's own sale flag treated as a price-drop signal, built-in new-listing and price-drop monitoring | No condition grade, seller identity or total-matches count — Pamono's own pages don't expose them |
| Checking Pamono by hand | Free, plus your time | Full control | Doesn't scale past a handful of searches and misses whatever appears between visits |

### Data & privacy

**Data & privacy.** This actor reads public search results that anyone can see without logging in.
It doesn't log in, solve CAPTCHAs or reveal hidden contact details. Pamono itself exposes no
seller identity on its listing cards, so none is collected. Not affiliated with Pamono.

### FAQ

**Is this allowed?**
It collects the same public listing data your browser shows, for the searches you
choose. It's built for monitoring a search, not for copying the marketplace. Check that your use
fits Pamono's terms and your local law.

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

**Why is `designer` sometimes empty?**
It's parsed from Pamono's own title text ("... by \<Designer>, \<Decade>"), not a
structured field Pamono provides — a title that doesn't follow that convention leaves it empty
rather than guessing.

**Why is `currency` sometimes different between two runs?**
Pamono decides the display currency per request and this build found no way to pin it down (see
"Currency" above); this actor reports whichever currency it was actually served.

**What do I need to set up?**
Nothing. No Pamono 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 "Pamono Scraper: New
Listing & Price Drop Alerts".

### Related actors

- [Chairish Listing Lookup](https://apify.com/accountable_eel/chairish-listing-lookup): the same
  one row per listing shape for Chairish's US vintage furniture and decor marketplace.
- [1stDibs Listing Lookup](https://apify.com/accountable_eel/1stdibs-listing-lookup): global
  luxury furniture and design, with 10-currency pricing and era tags.
- [Selency Listing Lookup](https://apify.com/accountable_eel/selency-listing-lookup): France's
  vintage furniture and decor marketplace, with material and style tags.
- [Vinted Listing Lookup](https://apify.com/accountable_eel/vinted-listing-lookup): new-listing and
  price-drop alerts across 22 Vinted second-hand fashion sites.

# Actor input Schema

## `searches` (type: `array`):

One search per line — any keyword (e.g. "teak armchair", "art deco mirror") or a pasted pamono.com category or search link. No login required. Accepted formats: teak armchair, art deco mirror, https://www.pamono.com/armchairs, https://www.pamono.com/catalogsearch/result/?q=chaise+lounge. You're only charged for the ones we actually find — a miss costs nothing.

## `testRun` (type: `boolean`):

Turn this on to test your input on a small sample before running the full list. Turn it off to process everything.

## `onlyFound` (type: `boolean`):

Only keep rows where something was actually found. Misses are always free, whether or not you show them here.

## `includeKeywords` (type: `array`):

Optional. Matched against the title and the parsed designer name.

## `excludeKeywords` (type: `array`):

Optional. Matched against the title and the parsed designer name.

## `maxResults` (type: `integer`):

Optional. Stop the run once this many results have been found — useful for a quick, cheap sample. Leave blank for no limit.

## `maxListingsPerSearch` (type: `integer`):

Pamono shows about 96 listings per page and does not expose a total-matches count; this actor pages until it reaches your limit or runs out of pages. You pay per listing returned, so this is also your budget control.

## `minPrice` (type: `integer`):

Optional. Applied after fetching (Pamono has no price-filter URL parameter). Leave empty for no minimum.

## `maxPrice` (type: `integer`):

Optional. Applied after fetching. Leave empty for no maximum.

## `deltaMode` (type: `boolean`):

Turns this actor into a monitor. Pamono shows no posting date, so this is the only way to see what's new. A listing counts as new when its Pamono ID has not been returned by a previous run of the same watchlist, and as a price drop when its price falls since it was last seen — including a listing that just went on Pamono's own sale. Already-seen, unchanged listings are dropped before you are billed, so a quiet run costs only the run fee. The first run has nothing to compare against, so (unless "Seed silently" is on) it returns everything and remembers it.

## `deltaName` (type: `string`):

Leave empty and we derive one from this run's search settings, so two schedules with different settings keep separate memories. Type your own name to keep one memory across a settings change, or to have two schedules share one.

## `alertOnNew` (type: `boolean`):

Include newly-seen listings when monitoring is on. Turn off to get price-drop alerts only.

## `alertOnPriceDrop` (type: `boolean`):

Include listings whose price dropped since this watchlist last saw them — including a listing seen for the first time already on Pamono's own sale. Turn off to get new-listing alerts only.

## `minPriceDropPct` (type: `integer`):

A listing must drop by at least this percentage since it was last seen by THIS monitor to be reported as a price-drop.

## `skipFirstRun` (type: `boolean`):

Instead of returning every current listing as "new" the first time a watchlist runs, this banks them silently and starts alerting from the second run on.

## `columns` (type: `array`):

Choose which pieces of information to include in each result row. All are included by default.

## `expandRows` (type: `boolean`):

When on, each listing found gets its own row instead of being grouped under its search. You're still only charged once per search, no matter how many rows it produces.

## `maxConcurrency` (type: `integer`):

Parallel requests. Keep conservative — this target has no browser fallback, so getting blocked costs more than slow-and-steady.

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

Apify Proxy config. Residential recommended for anti-bot-sensitive targets.

## Actor input object example

```json
{
  "searches": [
    "teak armchair"
  ],
  "testRun": false,
  "onlyFound": false,
  "includeKeywords": [],
  "excludeKeywords": [],
  "maxListingsPerSearch": 100,
  "deltaMode": false,
  "deltaName": "",
  "alertOnNew": true,
  "alertOnPriceDrop": true,
  "minPriceDropPct": 5,
  "skipFirstRun": false,
  "columns": [
    "searchQuery",
    "listingCount",
    "truncated",
    "newCount",
    "priceDropCount",
    "monitorStatus",
    "listings",
    "listingId",
    "title",
    "price",
    "currency",
    "regularPrice",
    "isDiscounted",
    "discountPct",
    "designer",
    "era",
    "imageUrl",
    "isSold",
    "changeType",
    "isNew",
    "previousPrice",
    "priceDropPct",
    "firstSeenAt",
    "url"
  ],
  "expandRows": true,
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (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 = {
    "searches": [
        "teak armchair"
    ],
    "includeKeywords": [],
    "excludeKeywords": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("accountable_eel/pamono-listing-lookup").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 = {
    "searches": ["teak armchair"],
    "includeKeywords": [],
    "excludeKeywords": [],
}

# Run the Actor and wait for it to finish
run = client.actor("accountable_eel/pamono-listing-lookup").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 '{
  "searches": [
    "teak armchair"
  ],
  "includeKeywords": [],
  "excludeKeywords": []
}' |
apify call accountable_eel/pamono-listing-lookup --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,accountable_eel/pamono-listing-lookup"
        }
    }
}
```

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/71SvgEROrxh2H1SdL/builds/FB2nF7Mo4s7jB2L6v/openapi.json
