# OLX Listing Watch (`lowlanddata/olx-listing-watch`) Actor

Watch one saved search on olx.pl and get only the NEW listings each run - built for hourly schedules with email, Slack or webhooks. Full listing data, no seller identity ever. Quiet runs cost nothing.

- **URL**: https://apify.com/lowlanddata/olx-listing-watch.md
- **Developed by:** [Lowland Data](https://apify.com/lowlanddata) (community)
- **Categories:** E-commerce, Automation, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.59 / 1,000 results

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## OLX Listing Watch — only what's new on OLX.pl

Watch one saved search on **OLX.pl** and get back **only the listings that appeared since your last run**. Set a query, an optional price band in złoty, a Schedule with an email or Slack step — and every fresh match lands in your inbox as clean, structured JSON. No dedupe logic on your side, no re-reading the same ads. The first run takes a baseline snapshot; every run after that delivers the difference.

Poland has several paid consumer apps selling exactly this alert. None of them gives you the data — an API, a webhook, a CSV, an MCP tool. This actor does, on the same GDPR-clean output as its parent, the [OLX.pl Scraper](https://apify.com/lowlanddata/olx-pl-scraper): seller names, contact routes and exact coordinates never leave the wire.

### Quick start (30 seconds)

1. Put what you'd type in the OLX search box into **searchQuery** — e.g. `rower gravel`.
2. Click **Start**. The first run returns the current matches as a baseline.
3. Add a Schedule (hourly works well) with an email or Slack integration. From now on, a run only delivers listings you haven't seen — and a quiet run delivers nothing.

Optional knobs: a `categoryId` instead of (or with) the query, a `priceMinPln`/`priceMaxPln` band in whole złoty, and `maxItems` per run.

### What you can build with it

- **Beat other buyers to underpriced gear.** Flippers watching a niche — `searchQuery: "konsola ps5"`, `priceMaxPln: 1200` — get each new listing minutes after it goes up, with `priceGrosz` parsed and `negotiable` flagged. The margin is in being first.
- **Feed a dealer's sourcing pipeline.** A small dealer watching stock sources runs one watch per supply niche, straight into a Make or n8n scenario that scores each new listing against buy criteria. No human refreshing search pages.
- **Wait for one specific item.** Looking for a discontinued lens or a specific bike frame? Set the watch once and forget it — the day it appears, the alert fires. Quiet weeks cost you nothing beyond the run start.
- **Alert an AI agent, not just a mailbox.** Through MCP, an assistant can run the watch itself, read only the new listings and decide what deserves your attention.

### What you get

Each new listing is one dataset item — the same shape as the parent OLX.pl Scraper, so anything built on one works on the other:

```json
{
  "listingId": "1090000001",
  "url": "https://www.olx.pl/d/oferta/rower-gorski-kross-level-3-CID767-ID14zZz1.html",
  "title": "Rower górski Kross Level 3 jak nowy",
  "description": "Sprzedam rower górski, mało używany, stan bardzo dobry.",
  "priceGrosz": 150000,
  "currency": "PLN",
  "negotiable": true,
  "postedAt": "2026-08-18T17:40:00+02:00",
  "refreshedAt": "2026-08-20T09:12:00+02:00",
  "city": "Kraków",
  "region": "Małopolskie",
  "categoryId": 767,
  "attributes": { "state": "Używane", "typ": "Górskie" },
  "sellerType": "private",
  "deliveryAvailable": true,
  "imageUrls": ["https://ireland.apollo.olxcdn.com/v1/files/example/image;s=1000x750"]
}
```

Category-specific specs come through in `attributes` — condition on any item, year and mileage on vehicles, floor area on property. Only a whitelist of non-personal attribute keys passes.

Field notes:

- `priceGrosz` is the asking price in grosz (1/100 PLN): `150000` = 1 500 zł. Free or swap listings carry no price.
- `postedAt` vs `refreshedAt`: sellers bump listings. The watch remembers each listing it has delivered, so a bump does **not** trigger a second alert — you hear about a listing once.
- `city`/`region` are municipality-level. Exact coordinates are deliberately never collected.
- `sellerType` (business or private) is the only seller-derived field in the output.
- The run's status message tells you the result at a glance: "12 new listings since the last run", or on the first run, "87 listings (baseline run - future runs deliver only new ones)".

### How much do OLX alerts cost?

$1.99 per 1,000 **new** listings delivered, pay-as-you-go. You pay for the difference, not the search:

- **A quiet run — nothing new — costs nothing beyond the actor start.** Most scheduled runs of a niche watch are quiet.
- **A niche producing 10 new listings a day ≈ $0.60 a month**, checked every hour.
- **A baseline run of 200 listings ≈ $0.40**, once.

The price is all-inclusive — platform usage is covered, datacenter proxies are enough, and runs finish in seconds, so even an hourly schedule stays light. Free-plan runs are capped at 25 items, enough to see the baseline-then-new mechanics work on your real search.

### Not technical? Let your AI assistant set it up

Copy this into ChatGPT, Claude or any AI assistant, fill in the one line, and follow the conversation:

```text
Help me set up the "OLX Listing Watch" actor on Apify
(https://apify.com/lowlanddata/olx-listing-watch). Guide me one step at a time.

What I want to be alerted about: [E.G. "gravel bikes under 3000 zł"]

Guide me to:
1. Propose my input values: searchQuery (what I'd type in the OLX search box),
   an optional priceMinPln/priceMaxPln band in złoty, and maxItems.
2. Create a free Apify account (apify.com), open the actor page, paste the values
   into the Input form, and start one run — that first run is my baseline snapshot.
3. Set up an hourly Schedule in the Apify Console with the same input, plus an
   email or Slack integration on finished runs, so every new listing reaches me
   without opening OLX.
4. If I want to watch a second search, show me how to add another Schedule with
   its own input and a different stateStoreName, so the two watches don't mix.
5. If the alerts are what I wanted, remind me at the end to leave a quick rating
   on the actor page, and to report anything broken on its Issues tab.
```

### Input

| Field                | Description                                                                                    |
| -------------------- | ---------------------------------------------------------------------------------------------- |
| `searchQuery`        | The saved search to watch, exactly as you'd type it on olx.pl.                                 |
| `categoryId`         | Numeric OLX category id to watch, instead of or together with the query.                       |
| `priceMinPln`        | Only listings costing at least this many złoty.                                                |
| `priceMaxPln`        | Only listings costing at most this many złoty.                                                 |
| `maxItems`           | Stop after this many new listings per run (default 200; free plan caps at 25).                 |
| `stateStoreName`     | Named store remembering what was already delivered — one per watched search.                   |
| `resetState`         | Forget everything seen so far; the next run delivers the current snapshot as a fresh baseline. |
| `proxyConfiguration` | Proxy settings; keep Apify proxy enabled.                                                      |

A run minimally needs a `searchQuery` or a `categoryId`; invalid input (like an inverted price band) fails immediately with the reason in the run's status message.

#### Finding a category ID

Open the category on olx.pl and read the id from the page URL, or run the [parent scraper](https://apify.com/lowlanddata/olx-pl-scraper) once broadly — every listing carries its `categoryId`, reusable here as input.

### Use it from your code

Runs finish in seconds, so the synchronous endpoint is a natural fit — one HTTP call returns only the new listings:

```bash
curl "https://api.apify.com/v2/acts/lowlanddata~olx-listing-watch/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -X POST -H "Content-Type: application/json" \
  -d '{"searchQuery": "rower gravel", "priceMaxPln": 3000}'
```

Node.js:

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('lowlanddata/olx-listing-watch').call({
  searchQuery: 'rower gravel',
  priceMaxPln: 3000,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
// items = only listings new since the previous run
```

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("lowlanddata/olx-listing-watch").call(
    run_input={"searchQuery": "rower gravel", "priceMaxPln": 3000})
items = client.dataset(run["defaultDatasetId"]).list_items().items
```

Schedules, finished-run webhooks and the Make/Zapier/n8n integrations all work out of the box — and because the dataset only ever contains new listings, a "dataset items → message" step is the whole pipeline.

### Use it with AI agents (MCP)

Claude, Cursor and other MCP-capable agents can run the watch as a tool through Apify's hosted MCP server — the agent checks the search, reads only what's new and acts on it.

Claude Code:

```bash
claude mcp add apify --transport http "https://mcp.apify.com?actors=lowlanddata/olx-listing-watch"
```

Cursor or Claude Desktop (add a custom connector / MCP server with this URL):

```text
https://mcp.apify.com?actors=lowlanddata/olx-listing-watch
```

Sign in with your Apify account when prompted — runs are billed to it. Setup details per client: [Apify MCP docs](https://docs.apify.com/platform/integrations/mcp), or start from this actor's own MCP page: [apify.com/lowlanddata/olx-listing-watch/api/mcp](https://apify.com/lowlanddata/olx-listing-watch/api/mcp).

Prompts that work once connected:

- "Check my OLX watch for 'rower gravel' and tell me if anything new under 3000 zł appeared."
- "Run the OLX watch and summarize the new listings — flag any private seller below 2000 zł."
- "Anything new on my OLX watch since this morning? Link the three cheapest."

### Is it legal to monitor OLX listings?

The watch reads public listing data — prices, descriptions, categories, city-level locations — and is built so the hard part of the GDPR question never arises: **no personal data enters your dataset in the first place.** The extractor maps a fixed whitelist of fields; the seller block, contact block and map coordinates are never read into the output. The only seller-derived value is the business-vs-private flag. Poland's data-protection authority (UODO) follows the same GDPR baseline as the rest of the EU, and an output with no seller personal data in it is the design, not a setting.

One honest limit: titles and descriptions are the seller's own words, delivered as-is with markup stripped. If a seller types contact details into their listing text, that text is not rewritten.

### Is there an OLX API for listing alerts?

No. OLX.pl offers saved-search notifications inside its own apps, but no API to read them, and its partner API serves advertisers posting ads, not buyers reading them. The Polish market has paid consumer alert services built on this gap — all of them notification-only. This actor is the API-first version: the same "only what's new" delivery, but as JSON you can pipe anywhere — email, Slack, a webhook, a spreadsheet, an AI agent.

### Does OLX block the watch?

OLX serves its listings openly to ordinary requests, and the watch stays well inside that welcome: it pages newest-first and stops as soon as it hits a streak of listings it has already seen, so a typical scheduled run touches only a page or two. Paced requests, standard datacenter proxies, no anti-bot circumvention — which is why runs finish in seconds and hourly schedules are unremarkable.

### How do I set up OLX alerts?

This actor **is** the alert engine — no `postedAfter` juggling, no dedupe step, no diffing datasets. The full setup:

1. Run once with your search — that's the baseline.
2. Add a Schedule in the Apify Console (hourly for competitive niches, daily for slow ones) with the same input.
3. Attach an email or Slack integration to finished runs. Because a run's dataset contains only new listings, the notification only ever shows you news.

Watching several searches? One Schedule per search, each with its own `stateStoreName`. The AI-assistant prompt above walks a non-technical user through all of it.

### FAQ

**How do I get OLX alerts?** Run this actor on a Schedule with your search as input and attach an email or Slack integration. Each run delivers only the listings that appeared since the previous one, so every notification is pure news. Setup takes a few minutes; the prompt in the AI-assistant section walks you through it.

**Can I get notified about new OLX listings by email?** Yes — that is the core use. Schedule the actor and add the Apify email integration on finished runs; Slack, webhooks and Make/Zapier/n8n work the same way.

**Why did my first run return listings I already saw on OLX?** The first run is a baseline snapshot: it delivers the current matches and remembers them. From the second run on, only listings new since the last run come through. The status message says which kind of run you got.

**Why did my run return zero listings?** Nothing new matched your search since the last run — a quiet run, which is normal and costs you nothing beyond the actor start. The status message confirms it.

**Why don't bumped ads trigger a new alert?** Sellers refresh listings to push them back to the top of OLX's newest-first order. The watch remembers every listing it has delivered for two months, so a bump of a listing you already saw is recognized and skipped — one listing, one alert.

**Can I watch several OLX searches at once?** Yes — set up one Schedule per search and give each its own `stateStoreName`. Each store remembers its own search independently; sharing one store between different searches mixes their memories.

**How do I reset a watch and start over?** Run once with `resetState: true`. The watch forgets everything it has seen and delivers the current snapshot as a fresh baseline; later runs go back to news-only.

**What happens if I change my search query?** Use a new `stateStoreName` (or set `resetState: true`) when you change what a watch looks for — the state store remembers one search, and reusing it for a different one gives misleading "new" results.

**Where do I find an OLX category id?** In the category page URL on olx.pl, or in the `categoryId` field of any scraped listing — run the parent OLX.pl Scraper once broadly and read it off the results.

**How much does a quiet run cost?** Nothing beyond the actor start — the $1.99 per 1,000 rate applies only to new listings actually delivered. A niche watch where most runs find nothing costs cents per month.

**How often should I schedule the watch?** Hourly for competitive niches where being first matters; daily for slow ones. Runs finish in seconds and quiet runs are nearly free, so err on the frequent side.

**How long does the watch remember a listing?** Two months per listing. A listing older than that could in principle re-alert if it resurfaces, but in practice OLX listings rarely live that long.

**Can I export the new listings to Excel or CSV?** Yes — every run's dataset exports as CSV, Excel, JSON or XML from the Apify Console or API, and it contains only that run's new listings.

**Does it work with Make, Zapier or n8n?** Yes — standard Apify actor, all platform integrations apply. Because the dataset is pre-filtered to news, a two-step scenario (run finished → send items) is complete.

**Can I get seller names or phone numbers?** No — by design, same whitelist as the parent scraper. The only seller information is whether the listing comes from a business or a private seller.

**Do I need residential proxies?** No. Datacenter proxies through the default Apify proxy setting are enough, which keeps runs cheap and fast.

**Is there an official OLX API for saved-search alerts?** No — OLX's own alerts live only inside its apps, and its partner API is for posting ads. This actor is the API-first alternative.

**Can Claude or another AI agent check my watch?** Yes, through Apify's MCP server — the agent runs the watch and reads only the new listings. See the MCP section above for the one-line setup.

### Related scrapers

The same GDPR-clean guarantee, same output discipline, across the OLX family:

- [OLX.pl Scraper](https://apify.com/lowlanddata/olx-pl-scraper) — the parent: full searches, category crawls beyond the 1,000-result window, date filters. Use it to explore; use this watch to stay informed.
- [OLX.ro Scraper](https://apify.com/lowlanddata/olx-ro-scraper) — Romania's OLX marketplace.
- [OLX.ua Scraper](https://apify.com/lowlanddata/olx-ua-scraper) — Ukraine's OLX marketplace.
- [OLX.pt Scraper](https://apify.com/lowlanddata/olx-pt-scraper) — Portugal's OLX marketplace.

### Troubleshooting

The actor fails fast with the reason in the run's status message:

- **"Provide a search query, a category id, or both."** — the watch needs a scope; add a `searchQuery` or `categoryId`.
- **"priceMinPln must not be higher than priceMaxPln."** — swap the two values.
- **A run fails saying the markup may have changed** — every fetched listing came back without a title and price, which means OLX changed its page structure rather than your search going quiet. The run fails loudly instead of silently reporting "nothing new"; report it on the Issues tab and it gets fixed.
- **The same watch suddenly re-delivered everything** — check whether `resetState` was left on `true`, or whether the `stateStoreName` changed between runs; either starts a fresh baseline.
- **Fewer items than expected on a free plan** — the 25-item free cap; run on a paid Apify plan for the full baseline.

### Support

Found an issue or missing something? Open an issue on the actor's **Issues tab** — reports get fixed, this actor is actively maintained.

Working well for you? A **rating on this page** takes ten seconds and helps other buyers find an API-first alert option among the notification apps — it is also the clearest signal of what to build next.

# Actor input Schema

## `searchQuery` (type: `string`):

The saved search to watch, exactly as you would type it on olx.pl, e.g. "rower gravel" or "iphone 15 pro". A query, a category id, or both.

## `categoryId` (type: `integer`):

Optional OLX category id to watch (find it in a category URL or any scraped listing's categoryId).

## `priceMinPln` (type: `integer`):

Only listings costing at least this much, in whole zloty.

## `priceMaxPln` (type: `integer`):

Only listings costing at most this much, in whole zloty.

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

Stop after this many new listings per run. Free-plan runs are capped at 25 items.

## `stateStoreName` (type: `string`):

Named store remembering which listings were already delivered, so scheduled runs emit only new ones. Use a different name to track several searches independently.

## `resetState` (type: `boolean`):

Forget everything seen so far and deliver the current snapshot as a fresh baseline.

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

Proxy settings. Keep Apify proxy enabled.

## Actor input object example

```json
{
  "searchQuery": "rower gravel",
  "maxItems": 25,
  "stateStoreName": "olx-listing-watch-state",
  "resetState": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `listings` (type: `string`):

New OLX listings since the last run, one JSON object per listing.

# 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 = {
    "searchQuery": "rower gravel",
    "maxItems": 25,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("lowlanddata/olx-listing-watch").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 = {
    "searchQuery": "rower gravel",
    "maxItems": 25,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("lowlanddata/olx-listing-watch").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 '{
  "searchQuery": "rower gravel",
  "maxItems": 25,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call lowlanddata/olx-listing-watch --silent --output-dataset

```

## MCP server setup

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

```

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/cQRlukmQTk7SmRV8g/builds/EsgmmRYcfb0gPvFQo/openapi.json
