# Pepper Deals Scraper — mydealz, hotukdeals, dealabs & 5 more (`northbell/pepper-deals-scraper`) Actor

Deals from all 8 Pepper communities in one run: mydealz, hotukdeals, dealabs, chollometro, pepper.pl, preisjaeger, nl.pepper, promodescuentos. Price, original price, discount, temperature, merchant, voucher code. Only new deals since the last run for alerts. No login.

- **URL**: https://apify.com/northbell/pepper-deals-scraper.md
- **Developed by:** [Northbell](https://apify.com/northbell) (community)
- **Categories:** E-commerce, Marketing
- **Stats:** 2 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 deals

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

## Pepper Deals Scraper — mydealz, hotukdeals, dealabs & 5 more

Read the deals from all eight Pepper deal communities in one run: **mydealz.de** (Germany), **hotukdeals.com** (UK), **dealabs.com** (France), **chollometro.com** (Spain), **pepper.pl** (Poland), **preisjaeger.at** (Austria), **nl.pepper.com** (Netherlands) and **promodescuentos.com** (Mexico). One clean row per deal: **title, price, original price, discount, temperature (the community's votes), merchant, voucher code, shipping, category, dates and the link**. **$1.00 per 1,000 deals**, no login, no API key.

**Try it now — the input is already filled in.** Press **Start**: the 30 newest deals on mydealz.de come back in about 3 seconds, for about $0.03.

| `title` | `price` | `originalPrice` | `discountPct` | `temperature` | `merchant` |
| --- | --- | --- | --- | --- | --- |
| Pokemon TCG: 30th Celebration (Amazon IT, FR, JP) | 54.99 |  |  | 1108.7 (isHot) | Amazon.it |
| Philips OneBlade 360 Face + Body QP2834/23 | 32.59 | 38.89 | 16.2 | 45.8 | Philips |
| Night train Munich to Rome | 34.9 |  |  | 73 | Urlaubspiraten |

`temperature` is the community vote that makes a deal hot. Switch on *Only new deals since the last run* and a run every few minutes returns just the deals you have not seen; leave it off and the deals seen last time come back with how their temperature moved since then (`temperatureChange`).

Built for alerts: switch on *Only new deals since the last run* and every run returns just the deals you have not seen yet. A newest-first list stops reading at the first page you already saw, so a run every few minutes reads one page per site, and a run that finds nothing new costs only the $0.0005 start fee.

### What you get

| Field | What it is |
|---|---|
| `title`, `url`, `dealId`, `site`, `country`, `list` | the deal, its link, its number on the site, which site (`mydealz.de` …), the country code, and which of your lists found it |
| `price`, `originalPrice`, `discountPct`, `currency` | the deal price, the price it is compared with (the site's "next best price", empty when the poster gave none), the discount in percent, and the site's currency (EUR, GBP, PLN or MXN) |
| `temperature`, `isHot`, `commentCount` | the community's vote score (the number shown next to each deal; it can be negative), whether it reached the hot page, and the number of comments |
| `merchant`, `merchantDomain` | the shop's name and the shop's web address (`Screwfix`, `www.screwfix.com`) |
| `voucherCode` | the code to use at checkout, when the deal has one and it is shown publicly |
| `freeShipping`, `shippingPrice` | free shipping, or the shipping price when the poster gave one |
| `kind`, `category`, `isLocal`, `isExpired` | the type (`Deal`), the site's category (`Electronics`, `Gaming` …), whether it is a local in-store offer, and whether it has ended |
| `publishedAt`, `startsAt`, `endsAt` | when it was posted, and the start and end dates when the poster gave them (UTC) |
| `imageUrl` | the deal's picture (300 × 300) |
| `isNewSinceLastRun`, `firstSeenAt`, `previousTemperature`, `temperatureChange` | the change since your previous run of the same list: empty on the first run; after that `true` for deals you have not seen, and how much the temperature rose or fell |
| `observedAt` | when this row was read |

Every list (each site, and each keyword on each site) also gets one free `summary` row: `listUrl`, `dealsRead`, `dealsReturned`, `newSinceLastRun`, `filteredOut` (expired or below your minimum temperature), `pagesFetched`, `firstRun` and `stoppedBecause` (`limit`, `end-of-list`, `reached-last-run`, `page-limit`, `time-limit` or `error`). A list that cannot be read gives an `error` row. Both are free.

Shape of a row (shortened):

```json
{
  "type": "deal", "list": "mydealz.de: lego", "site": "mydealz.de", "country": "DE", "dealId": "2855742",
  "url": "https://www.mydealz.de/deals/lego-60419-polizeistation-auf-der-gefangnisinsel-2855742",
  "title": "Lego 60419 - Polizeistation auf der Gefängnisinsel", "kind": "Deal",
  "merchant": "Thalia", "merchantDomain": "www.thalia.de",
  "price": 68.05, "originalPrice": 71.89, "discountPct": 5.3, "currency": "EUR",
  "freeShipping": null, "shippingPrice": null, "voucherCode": "LEGO15",
  "temperature": 154.4, "commentCount": 7, "isHot": true, "isExpired": false, "isLocal": false,
  "category": "Family & Kids", "publishedAt": "2026-10-18T16:40:06.000Z", "startsAt": null, "endsAt": "2026-10-18T21:59:01.000Z",
  "imageUrl": "https://static.mydealz.de/threads/raw/fwAf9/2855742_1/re/300x300/qt/60/2855742_1.jpg",
  "isNewSinceLastRun": true, "firstSeenAt": "2026-10-19T03:03:00.995Z", "previousTemperature": null, "temperatureChange": null,
  "observedAt": "2026-10-19T03:03:00.995Z"
}
```

### Run it again and again

- **On a schedule** — save your input as a task and add a **Schedule**: every 10 minutes, every hour or every morning. Send each run to Slack, Discord, Telegram, Google Sheets or email with an integration on the task.
- **Watch for changes** — Turn on **Only new deals since the last run**.
- **In bulk** — Pick every site you want in **Sites** and put every keyword in one run.

### Use it for

- **Deal alerts** — every new deal on mydealz, hotukdeals and dealabs, or only the ones for `lego`, `ps5` or `rtx 5070`, or only deals above 100°, straight into your channel
- **Deal and coupon sites** — feed your own site, app or newsletter with fresh deals and voucher codes from eight countries
- **Retail and pricing teams** — see which of your products or your competitors' products the community posts, at what price, and how hot they get
- **Market research** — which shops, brands and categories get the most votes in each country

### Input

```json
{
  "sites": ["mydealz.de", "hotukdeals.com", "dealabs.com"],
  "searches": ["lego", "https://www.mydealz.de/gruppe/gaming"],
  "list": "new",
  "maxDealsPerList": 30,
  "onlyNew": true,
  "minTemperature": 0,
  "includeExpired": false
}
```

- **sites** — the Pepper sites to read. Keywords are searched on each of them.
- **searches** — optional. A keyword (searched newest first on every site you picked), or the address of a list page on a Pepper site: a category, a shop, or a search you set up on the site. An address is read on its own site only. Leave it empty to read each site's newest deals.
- **list** — when no keywords are given: `new` (every new deal, newest first) or `hot` (the front page).
- **maxDealsPerList** — how many deals to read for each site and each keyword, 30 per page (default 30, up to 1,200).
- **onlyNew** — return only deals you have not seen in an earlier run of the same list.
- **minTemperature**, **includeExpired** — leave out cold deals and deals that have ended (expired deals are left out unless you ask for them).

The memory behind *since the last run* is kept per list in a named key-value store in your Apify account, so the second run of the same list already shows what is new. A list is the same list when its site and keyword (or address) are the same.

### Pricing

**$1.00 per 1,000 deals** ($0.001 each), plus $0.0005 per run. Summary rows and error rows are free. With *Only new deals since the last run* you are charged only for the deals returned, so a run every 10 minutes that finds 3 new deals on each of 3 sites costs about $0.01.

### Notes

- **Public data only**: what anyone sees on the deal lists without signing in. The name, profile and picture of the person who posted a deal are not returned.
- **Speed**: one page of 30 deals per site every 1.5 seconds; different sites are read one after the other without waiting for each other. 40 pages (1,200 deals) is the deepest a list goes.
- **Fixed 21 Oct 2026**: keywords and the `hot` list had been reading each site's newest deals instead (a "lego" search returned 1 Lego deal in 89; now 72 in 74). If you scheduled a keyword with *Only new deals*, the next run returns the keyword's deals as new once.
- **Fixed 22 Oct 2026**: deals the previous run had simply not reached (it stopped at *max deals*) counted as new, so with *Only new deals* a second run could return older deals as new and charge for them. New now means the deal entered the part of the list the previous run read, or was posted after that run.
- **Keywords** are searched with the site's own search, newest first. For a word with very few matches the site may also show a few related deals; they are returned as the site shows them.
- **Since the last run**: deals are remembered for 30 days, up to 5,000 per list. On the first run `isNewSinceLastRun` is empty and *Only new deals* returns everything it read. On a newest-first list (the `new` list and keywords) the Actor stops at the first page where every deal was already seen; category and shop addresses are read to *Deals to read per list* every time, because they are not always sorted by date.
- **Prices** are as the poster entered them. `originalPrice` and `discountPct` are empty when no comparison price was given, and `price` is empty when the poster gave no price (for example a percentage-off sale).
- **Expired deals** appear in keyword results and category pages. They are filtered out by default and counted in the summary's `filteredOut`.
- If a site refuses the requests the list gets an error row; busy responses (429) and connection errors are retried twice. The Actor does not get around bot checks: if a site shows one, that site is skipped for the rest of the run and the other sites still run.

### For AI agents

`{"sites": ["hotukdeals.com"], "searches": ["air fryer"], "maxDealsPerList": 30}` returns up to 30 deal rows, newest first, plus one summary row. Rows have `type`: `deal`, `summary` or `error`. To watch over time, call it again with the same input and `"onlyNew": true`: every deal row returned is new since the previous call.

# Actor input Schema

## `sites` (type: `array`):

Which Pepper deal communities to read. Pick several to watch many countries in one run. Keywords below are searched on every site you pick.

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

Leave empty to read each site's newest deals (or the front page, see List). One per line: a keyword such as "lego" (searched on every site above, newest first), or the address of a list page on a Pepper site, such as a category or a shop (https://www.mydealz.de/gruppe/gaming). An address is read on its own site only.

## `list` (type: `string`):

new = every new deal, newest first. hot = the site's front page (the hottest deals right now).

## `maxDealsPerList` (type: `integer`):

How many deals to read for each site and each keyword, 30 per page, up to 1,200. With "Only new deals" switched on, this is how deep to look; only the new ones are returned and charged, and a newest-first list stops at the first page you already saw.

## `onlyNew` (type: `boolean`):

Return only deals you have not seen in an earlier run of the same list. The first run has nothing to compare with and returns everything it read. Good for alerts every few minutes: a run that finds nothing new costs only the start fee.

## `minTemperature` (type: `integer`):

Only deals at or above this temperature (the community's votes, the number shown next to each deal). For example 100 for deals that are already hot. Leave empty for all.

## `includeExpired` (type: `boolean`):

Keyword searches and category pages also show deals that have ended. They are left out unless you switch this on.

## Actor input object example

```json
{
  "sites": [
    "mydealz.de"
  ],
  "list": "new",
  "maxDealsPerList": 30,
  "onlyNew": false,
  "includeExpired": false
}
```

# Actor output Schema

## `deals` (type: `string`):

Title, price, discount, temperature, merchant, voucher code and the link to each deal.

## `lists` (type: `string`):

One row per site and keyword: how many deals were read, returned and new since the last run.

# 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 = {
    "sites": [
        "mydealz.de"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("northbell/pepper-deals-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 = { "sites": ["mydealz.de"] }

# Run the Actor and wait for it to finish
run = client.actor("northbell/pepper-deals-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 '{
  "sites": [
    "mydealz.de"
  ]
}' |
apify call northbell/pepper-deals-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,northbell/pepper-deals-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/S8rkejJOk2ZAMrN1Q/builds/NF74Ihs2uyznu7Axw/openapi.json
