# Trade Me Property Listing Monitor (`automation-lab/trade-me-property-listing-monitor`) Actor

Monitor public Trade Me Property searches for new listings, displayed-price changes, and listing updates in one structured change feed.

- **URL**: https://apify.com/automation-lab/trade-me-property-listing-monitor.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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

## Trade Me Property Listing Monitor

Monitor public Trade Me Property sale and rental searches for new listings, price changes, and listing updates.

### What does it do?

This Actor turns public Trade Me Property search pages into a structured listing change feed.

It reads the same public residential search data visible in the Trade Me browser experience.

Every result includes the listing URL, price display, location, property facts, agency context, images, and monitoring timestamps.

Run it again with the same state store to distinguish new, price-changed, updated, and unchanged listings.

### Who is it for?

- 🏠 Buyer agents watching a shortlist of New Zealand property searches.
- 📈 Property investors tracking supply and price movement.
- 🏢 Market analysts building regional listing datasets.
- 🏘️ Rental teams monitoring public rental inventory.
- 🔧 Developers sending listing changes to a CRM, sheet, or webhook.

### Why use a monitor?

A one-off property export answers what is listed now.

A monitor answers what changed since the previous run.

Use `firstSeenAt`, `lastSeenAt`, and `changeType` to create alerts or refresh downstream records.

### Supported sources

Use public Trade Me Property residential search URLs.

Sale example: `https://www.trademe.co.nz/a/property/residential/sale/search`.

Rental example: `https://www.trademe.co.nz/a/property/residential/rent/search`.

Copy a filtered public search URL from Trade Me when you want a narrower location or price scope.

### Quick start

1. Open a public Trade Me Property sale or rental search.
2. Copy its URL into `searchUrls`.
3. Start with `maxItems: 20`.
4. Leave `persistState` enabled for recurring monitoring.
5. Schedule repeat runs in Apify.

### Input: search URLs

`searchUrls` is required.

Provide one or more public Trade Me Property search page URLs.

The Actor rejects non-Trade-Me or non-property URLs rather than silently scraping an unrelated target.

### Input: maximum listings

`maxItems` caps records across all supplied searches.

Start small while designing a workflow.

Increase it when you need a larger search export.

The public endpoint returns up to 100 results per search request.

### Input: persisted state

Set `persistState` to `true` to maintain listing history.

On the first run, listings are labelled `new`.

On later runs, listings can be `unchanged`, `price_changed`, or `updated`.

### Input: state store name

`stateStoreName` selects the named key-value store used for history.

Keep it stable between runs for one monitoring workflow.

Use a different name when monitoring a separate buyer brief or market segment.

### Output fields

| Field | Description |
| --- | --- |
| `listingId` | Stable Trade Me listing identifier |
| `listingUrl` | Public listing page URL |
| `title` | Listing title |
| `listingType` | Sale, rent, or unknown |
| `price` | Current displayed price text |
| `address` | Public street address when provided |
| `suburb`, `district`, `region` | Location fields |
| `bedrooms`, `bathrooms` | Property facts when supplied |
| `propertyType` | Property classification |
| `agency`, `agents` | Public agency context |
| `openHomes` | Open-home data when supplied |
| `images` | Public listing image URLs |
| `firstSeenAt`, `lastSeenAt` | Monitoring timestamps |
| `changeType` | New, price changed, updated, or unchanged |

### Change types

`new` means the listing was not present in the saved state.

`price_changed` means the displayed price text changed.

`updated` means another monitored public attribute changed.

`unchanged` means the monitored fields matched the preceding snapshot.

### Example input

```json
{
  "searchUrls": [{"url": "https://www.trademe.co.nz/a/property/residential/sale/search"}],
  "maxItems": 25,
  "persistState": true,
  "stateStoreName": "auckland-buy-brief"
}
````

### Sale listing workflow

Run a sale search every morning.

Filter the dataset to `changeType` values other than `unchanged`.

Send new or price-changed rows to a buyer agent for review.

### Rental listing workflow

Use a public rental search URL for rental market coverage.

Collect price, bedroom count, locality, agency, and images in one export.

Use a separate state store from your sale-monitor workflow.

### Data quality

Fields are emitted from the public Trade Me search response.

Some listings may not expose an address, bathroom count, agent, or open-home schedule.

Those fields are returned as `null`, empty arrays, or omitted source values rather than guessed values.

### Limits and tips

Keep monitoring searches specific and schedule them at a sensible interval.

Avoid duplicate URLs in one run.

Use multiple state-store names for independent client or location workflows.

Treat displayed price text as the source value; negotiation listings may not have a numeric price.

### Integrations

- 📊 Export changed rows to Google Sheets for an agent’s daily review.
- 🔔 Send `new` and `price_changed` records to Slack or email automation.
- 🧩 Upsert `listingId` records into Airtable, HubSpot, or a warehouse.
- 🗺️ Join locality fields with an internal property-market dataset.

### API usage — Node.js

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/trade-me-property-listing-monitor').call({
  searchUrls: [{ url: 'https://www.trademe.co.nz/a/property/residential/sale/search' }],
  maxItems: 20,
  persistState: true,
});
console.log(await client.dataset(run.defaultDatasetId).listItems());
```

### API usage — Python

```python
from apify_client import ApifyClient
client = ApifyClient('APIFY_TOKEN')
run = client.actor('automation-lab/trade-me-property-listing-monitor').call(run_input={
    'searchUrls': [{'url': 'https://www.trademe.co.nz/a/property/residential/rent/search'}],
    'maxItems': 20,
    'persistState': True,
})
print(client.dataset(run['defaultDatasetId']).list_items().items)
```

### API usage — cURL

```bash
curl "https://api.apify.com/v2/acts/automation-lab~trade-me-property-listing-monitor/runs?token=$APIFY_TOKEN" \
  -H 'content-type: application/json' \
  -d '{"searchUrls":[{"url":"https://www.trademe.co.nz/a/property/residential/sale/search"}],"maxItems":20}'
```

### MCP

Use this Actor from Claude Desktop or Claude Code through Apify MCP.

For Claude Code, connect directly to this Actor's HTTP MCP tools:

```bash
claude mcp add apify-trade-me-property --transport http \
  "https://mcp.apify.com?tools=automation-lab/trade-me-property-listing-monitor"
```

For Claude Desktop or another HTTP MCP client, add this actor-specific server URL:

```json
{
  "mcpServers": {
    "apify-trade-me-property": {
      "type": "http",
      "url": "https://mcp.apify.com?tools=automation-lab/trade-me-property-listing-monitor"
    }
  }
}
```

Authenticate the Apify MCP connection with your Apify token when your client prompts for it.

Example prompt: “Monitor this Trade Me sale search and return listings with a changed price since the last run.”

Example prompt: “Export new Trade Me rental listings from this search as a table.”

### Scheduling

A daily schedule works well for broad market monitoring.

Use more frequent runs only for a narrow high-priority buyer brief.

Persisted state is what makes scheduled runs useful as a change feed.

### Legality and responsible use

Use only public pages and data you are entitled to process.

Respect Trade Me’s terms, applicable privacy law, and reasonable request volume.

Do not use this Actor for account-only data, login automation, or contact-data misuse.

### Troubleshooting

#### Why is a field empty?

Trade Me does not expose every field on every listing search card.

The Actor preserves the absence instead of inventing a value.

#### Why are all records `new`?

Confirm `persistState` is enabled and keep the same `stateStoreName` between runs.

#### Why did a URL fail?

Use a public `www.trademe.co.nz/a/property/...` sale or rental search URL.

### FAQ

#### Does this require a Trade Me account?

No. It uses public property search data and does not accept credentials.

#### Does it scrape listing detail pages?

The first release uses the public search response, which already includes the core monitoring fields.

#### Can I monitor both sale and rental listings?

Yes. Add both public search URLs to `searchUrls`.

### Related scrapers

For complementary New Zealand property coverage, see [Homes.co.nz tools](https://apify.com/automation-lab/homes-co-nz-scraper).

Use this Actor when the source-specific Trade Me listing change feed is the requirement.

### Pricing

Pricing is per produced listing plus a small run start event.

Your exact tiered price is shown in the Apify Console before you run.

Start with a small result cap to validate your workflow.

### Support

Include the input URL, run ID, and a short description when reporting an issue.

Do not include credentials; this Actor does not need them.

# Actor input Schema

## `searchUrls` (type: `array`):

Public Trade Me Property sale or rental search pages to monitor. Copy a filtered search URL from Trade Me.

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

Cap the number of listings returned across all searches.

## `persistState` (type: `boolean`):

Save first-seen timestamps and identify new, price-changed, updated, and unchanged listings on later runs.

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

Optional named key-value store for this monitor's history. Keep the same name between runs.

## Actor input object example

```json
{
  "searchUrls": [
    {
      "url": "https://www.trademe.co.nz/a/property/residential/sale/search"
    }
  ],
  "maxItems": 20,
  "persistState": true,
  "stateStoreName": "trade-me-property-listing-monitor-state"
}
```

# Actor output Schema

## `overview` (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 = {
    "searchUrls": [
        {
            "url": "https://www.trademe.co.nz/a/property/residential/sale/search"
        }
    ],
    "maxItems": 20,
    "persistState": true,
    "stateStoreName": "trade-me-property-listing-monitor-state"
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/trade-me-property-listing-monitor").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 = {
    "searchUrls": [{ "url": "https://www.trademe.co.nz/a/property/residential/sale/search" }],
    "maxItems": 20,
    "persistState": True,
    "stateStoreName": "trade-me-property-listing-monitor-state",
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/trade-me-property-listing-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchUrls": [
    {
      "url": "https://www.trademe.co.nz/a/property/residential/sale/search"
    }
  ],
  "maxItems": 20,
  "persistState": true,
  "stateStoreName": "trade-me-property-listing-monitor-state"
}' |
apify call automation-lab/trade-me-property-listing-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=automation-lab/trade-me-property-listing-monitor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Trade Me Property Listing Monitor",
        "description": "Monitor public Trade Me Property searches for new listings, displayed-price changes, and listing updates in one structured change feed.",
        "version": "0.1",
        "x-build-id": "4105JOa5O5e7bMfhq"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/automation-lab~trade-me-property-listing-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-automation-lab-trade-me-property-listing-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/automation-lab~trade-me-property-listing-monitor/runs": {
            "post": {
                "operationId": "runs-sync-automation-lab-trade-me-property-listing-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/automation-lab~trade-me-property-listing-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-automation-lab-trade-me-property-listing-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "searchUrls"
                ],
                "properties": {
                    "searchUrls": {
                        "title": "🔎 Trade Me Property search URLs",
                        "type": "array",
                        "description": "Public Trade Me Property sale or rental search pages to monitor. Copy a filtered search URL from Trade Me.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "maxItems": {
                        "title": "Maximum listings per run",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Cap the number of listings returned across all searches.",
                        "default": 20
                    },
                    "persistState": {
                        "title": "Track changes between runs",
                        "type": "boolean",
                        "description": "Save first-seen timestamps and identify new, price-changed, updated, and unchanged listings on later runs.",
                        "default": true
                    },
                    "stateStoreName": {
                        "title": "State store name",
                        "type": "string",
                        "description": "Optional named key-value store for this monitor's history. Keep the same name between runs.",
                        "default": "trade-me-property-listing-monitor-state"
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
