# Luxury Sale Tracker: SSENSE Price Drop Alerts (`accountable_eel/luxury-sale-price-lookup`) Actor

SSENSE sale scraper and price tracker: every designer product on sale with sale price, retail price, discount % and category, one row per product. Filter by designer, discount or price, and get price-drop and new-on-sale alerts in Slack, Discord or Telegram. No login or API key.

- **URL**: https://apify.com/accountable_eel/luxury-sale-price-lookup.md
- **Developed by:** [Adriana 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 $3.04 / 1,000 sale product 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

## Luxury Sale Tracker: SSENSE Price Drop Alerts

Every designer product on **SSENSE's sale**, one row each: **sale price, retail price, discount %, category and a link**. Filter by designer, minimum discount or maximum price, and switch on monitoring to be told when a price **drops**, a product goes **on sale**, comes **back in stock**, or **leaves the sale**, in Slack, Discord or Telegram.

It reads SSENSE's public sale listing pages. No login, no cookies, no API key, no images.

### Who uses this

- **Resellers** who buy designer menswear and womenswear on sale to sell on again (Grailed, Vinted, Vestiaire): filter to the brands you resell and a minimum discount, get an alert when the price falls.
- **Deal newsletters and Discord / Telegram channels** that post designer sales: one run a day, an alert only for what changed.
- **Shoppers and stylists** watching one designer: put the name in the list and get that designer's sale items, cheapest first in your own sheet.

### Try it in 30 seconds

Press **Start** with the pre-filled input. It reads the first page of SSENSE's men's sale (120 products) and returns one row per product. One request.

### Example: one designer, deep discounts, a Discord alert

```json
{
  "designers": ["Rick Owens", "Acne Studios"],
  "gender": "men",
  "minDiscountPct": 40,
  "deltaMode": true,
  "deltaName": "my-resale-watchlist",
  "alertOnChangeOnly": true,
  "notifyUrl": "<your Discord webhook URL>"
}
```

Each designer is read from SSENSE's own page for that designer, so this is two requests, not a scan of the whole sale. Run it daily on a schedule: the first run is the baseline, and from the second run you only get (and only pay for) the products that are new on sale, dropped in price, came back, or left the sale.

### How to use

1. **In the Apify Console.** Open the actor page and click **Start** — the `designers` 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~luxury-sale-price-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"designers":["<example>"]}'
   ```
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.

### Input

```json
{
  "designers": []
}
```

One designer per line, written as SSENSE spells it. Leave empty for the whole sale section. Each designer is read from SSENSE's own page for that designer (one search each, up to 20), and only that designer's products are kept. Accepted formats: Rick Owens, Acne Studios, Comme des Garçons Homme, A.P.C..

Everything else is optional: `gender` (men or women), `locale` (en-us for USD, en-gb for GBP), `minDiscountPct`, `maxPricePerItem`, `maxItems`, `maxPages`, and the monitoring and alert fields (`deltaMode`, `deltaName`, `alertOn`, `minPriceDropPct`, `alertOnChangeOnly`, `skipFirstRun`, `notifyUrl`, `notifyFormat`, `maxNotificationsPerRun`).

### What you get

| Field | Meaning |
|---|---|
| `store`, `gender` | `ssense`, and the sale section (men or women). |
| `brand`, `name`, `url` | The designer, the product name and its SSENSE page (a link only: the actor never opens a product page). |
| `currency`, `price` | The price now, in the currency of the site version you chose. |
| `originalPrice`, `discountPct` | The retail price before the sale and the discount against it. |
| `category` | SSENSE's category path, for example `Clothing > Tops > T-Shirts`. |
| `inStock` | `true` when SSENSE lists the product as available. |
| `checkedAt` | When the run looked. |
| `changeType`, `previousPrice`, `changePct`, `lowestEverSeen`, `firstSeenAt` | Monitoring only: `new-on-sale`, `price-drop`, `price-rise`, `back-in-stock`, `gone` or `unchanged`, the price last time, the change in percent, the lowest price this watchlist has seen and when it first saw the product. Empty when monitoring is off. |

### Example output

| query | found | status | store | gender | brand | name | url | currency | price | originalPrice | discountPct | category | inStock | checkedAt | changeType | previousPrice | changePct | lowestEverSeen | firstSeenAt | scrapedAt |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| example | true | OK | <store> | <section> | <brand> | <product> | <link> | <currency> | <sale price> | <retail price> | \<discount (%)> | <category> | <in stock> | <checked at> | <change since last run> | <previous price> | \<change (%)> | <lowest price seen> | <first seen at> | 1970-01-01T00:00:00.000Z |

### Monitoring in three steps

1. Switch on **Track prices across runs** and give the watchlist a name.
2. Schedule the actor daily. The first run is the baseline (turn on **Seed silently** if you do not want it returned or billed).
3. Paste a Discord or Slack webhook (or a Telegram bot link) into **Send alerts to**. After each billed row an alert goes out with the product, the sale price, the retail price and the link. The first run of a watchlist sends nothing.

A product is reported **gone** only when the run read the whole list to its last page and a product it remembered from the earlier run of that same list was no longer there. A run cut short by `maxItems`, `maxPages` or the time limit never reports gone.

### Limits, stated plainly

- **SSENSE only.** Farfetch is not part of this actor yet.
- **Listing pages only.** The actor reads the sale listing and designer sale pages and nothing else: no product pages, no sizes, no images, no descriptions, no account, bag or checkout.
- **Sale sections only.** Men's and women's sale; not new arrivals, not kids.
- **Designers are matched by name** (accents, case and punctuation ignored): "Rick Owens" does not also return "Rick Owens DRKSHDW", which SSENSE lists as its own designer. Write the name as SSENSE spells it; a designer SSENSE has no sale page for comes back as not found and is not charged.
- **Pages are scanned in SSENSE's own order**, up to `maxPages`. With narrow filters raise `maxPages` (up to 20 pages, 2,400 products); the men's sale is about 40 pages.
- **Prices are the site version's currency** (US dollars on en-us, British pounds on en-gb). Changing the site version starts a fresh baseline for the products it shows.
- **One request at a time**, about one per second at most.
- SSENSE's terms of service prohibit automated data collection. You are responsible for how you use the data.

### Pricing

Pay-per-event. A flat per-run fee covers session/proxy warmup; you're billed
per item only when data is actually found and returned — see
`.actor/pay_per_event.json` for exact prices. A miss is never charged.

### FAQ

**Do I pay for products my filters remove?** No. Only the rows you receive are billed. A run that returns nothing costs the start fee only, plus nothing per product.

**Why does an unchanged product cost nothing in monitoring?** With **Only return products that changed** on, a product that did not move writes no row and is not billed.

**Can I run men's and women's together?** Run the actor twice (two tasks), once per section, with the same watchlist name pattern.

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~luxury-sale-price-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"designers":["<example>"]}'
```

**n8n.** Add an HTTP Request node: Method `POST`, URL `https://api.apify.com/v2/acts/accountable_eel~luxury-sale-price-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, Body Content Type `JSON`, JSON Body `{"designers":["<example>"]}` (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~luxury-sale-price-lookup/run-sync-get-dataset-items?token=<YOUR_TOKEN>`, Body `{"designers":["{{sale product}}"]}`, mapping the row's sale product into the `designers` array.

**MCP.** In Claude, Cursor, or any MCP client with the Apify MCP server, ask for "SSENSE Sale Scraper: Price Drops & Discount Alerts" — the agent will find and run this actor.

# Actor input Schema

## `designers` (type: `array`):

One designer per line, written as SSENSE spells it. Leave empty for the whole sale section. Each designer is read from SSENSE's own page for that designer (one search each, up to 20), and only that designer's products are kept. Accepted formats: Rick Owens, Acne Studios, Comme des Garçons Homme, A.P.C.. You're only charged for the ones we actually find — a miss costs nothing.

## `gender` (type: `string`):

Which SSENSE sale section to read. Men's or women's sale; run twice (two tasks) for both.

## `locale` (type: `string`):

en-us shows prices in US dollars, en-gb in British pounds (each site version has its own sale prices and page count).

## `minDiscountPct` (type: `integer`):

Keeps only products whose discount against the retail price is at least this much (for example 50). Applied after the fetch.

## `maxPricePerItem` (type: `integer`):

Keeps only products priced at or below this amount, in the currency of the site version. Applied after the fetch.

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

Stops once this many products matched your filters. SSENSE lists 120 per page.

## `maxPages` (type: `integer`):

Each page of 120 sale products is one request. With narrow filters the actor keeps scanning pages until it has your products or reaches this limit (the sale list is up to 40 pages).

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

Turns the actor into a sale monitor. Each run compares every product with the previous run's and fills in 'Change since last run', previous price, change % and the lowest price seen. Schedule it daily and combine with 'Only return products that changed' and 'Send alerts to'.

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

Leave empty and one is derived from your section, site version and filters. Type your own name to keep one memory across changes, or to run several independent watchlists.

## `alertOn` (type: `string`):

Which changes count. 'Everything' = new on sale, price drop, back in stock and gone. A price rise is returned but never alerted.

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

A price move smaller than this counts as unchanged.

## `alertOnChangeOnly` (type: `boolean`):

With monitoring on, only products matching 'Report and alert on' are returned and billed. A product whose price did not move writes no row and costs nothing.

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

The first run of a watchlist has nothing to compare with. Turn this on to remember it without returning or billing it, so alerts start from the second run.

## `notifyUrl` (type: `string`):

Optional. After a product row is billed, each alert (as chosen above) is posted here as one message with the product, price, retail price and link. Discord or Slack: paste the channel's webhook URL. Telegram: https://api.telegram.org/bot<token>/sendMessage?chat_id=<chat id>. Any other URL receives JSON. Messages are free, a failed message never fails the run, and the first run of a watchlist sends nothing (it is the baseline). Stored encrypted, never logged or written to the results.

## `notifyFormat` (type: `string`):

Leave on 'Detect from the link': discord.com links get Discord messages, hooks.slack.com Slack, api.telegram.org Telegram, anything else JSON. Pick one only to override that.

## `maxNotificationsPerRun` (type: `integer`):

Up to 100. After this, one 'more alerts' message says the rest are in the run's dataset. 0 sends only that one message.

## `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. Only keep results that mention at least one of these words (e.g. a job title, a city, a product name). Leave empty to keep everything.

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

Optional. Drop any result that mentions one of these words. Leave empty to skip nothing.

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

## `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 sale product found gets its own row instead of being grouped under its sale product. You're still only charged once per sale product, 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
{
  "designers": [],
  "gender": "men",
  "locale": "en-us",
  "maxItems": 120,
  "maxPages": 3,
  "deltaMode": false,
  "deltaName": "",
  "alertOn": "all",
  "minPriceDropPct": 5,
  "alertOnChangeOnly": false,
  "skipFirstRun": false,
  "notifyFormat": "auto",
  "maxNotificationsPerRun": 20,
  "testRun": false,
  "onlyFound": false,
  "includeKeywords": [],
  "excludeKeywords": [],
  "columns": [
    "store",
    "gender",
    "brand",
    "name",
    "url",
    "currency",
    "price",
    "originalPrice",
    "discountPct",
    "category",
    "inStock",
    "checkedAt",
    "changeType",
    "previousPrice",
    "changePct",
    "lowestEverSeen",
    "firstSeenAt"
  ],
  "expandRows": true,
  "maxConcurrency": 1,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ]
  }
}
```

# 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 = {
    "designers": [],
    "includeKeywords": [],
    "excludeKeywords": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("accountable_eel/luxury-sale-price-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 = {
    "designers": [],
    "includeKeywords": [],
    "excludeKeywords": [],
}

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,accountable_eel/luxury-sale-price-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/awo9RbfUYUnmPKMUM/builds/jvCGSWGmLfNFXtEIn/openapi.json
