# Trade Me NZ Scraper - Marketplace, Property, Motors & Jobs (`abotapi/trademe-co-nz-scraper`) Actor

Scrape trademe.co.nz across all five sections: Marketplace goods and auctions, Property, Motors, Jobs and Services. Search or paste URLs, walk pagination, and enrich with full detail plus seller feedback (positive/negative counts and score).

- **URL**: https://apify.com/abotapi/trademe-co-nz-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Categories:** E-commerce, Real estate, Jobs
- **Features:** Limited permissions
- **Stats:** 42 total users, 10 monthly users, 98.3% runs succeeded, 2 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 listing 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?

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

## Trade Me Scraper: Listings Across Marketplace, Property, Motors, Jobs and Services

Trade Me Scraper turns New Zealand's largest online marketplace into clean structured data. Collect listings from Marketplace, Property, Motors, Jobs and Services in one actor, with prices, locations, photos, listing specifics and, on request, full descriptions and seller feedback. Search by keyword and filters, or paste category, search and individual listing links, then export to JSON, CSV or Excel, or pull the results straight into your app through the API.

### Why This Scraper?

- **Five sections, one actor.** Marketplace, Property, Motors, Jobs and Services, so you don't need a different tool for each part of Trade Me.
- **Two ways to search.** Keywords with filters for each section, or paste category, search and individual listing links.
- **Section-specific fields on every record.** Bedrooms and land area for Property, make, model, year and odometer for Motors, salary range for Jobs, plus the fields common to every listing.
- **Optional full detail and seller feedback.** Description, the full photo gallery, agent contact details, and a member's feedback score and history, only when you turn on full detail.
- **Walks the whole result list.** Collects as many result pages as a search has, or a limit you set, and stops once your item limit is reached.
- **Resume long or interrupted walks.** Continue from a previous run's dataset so a later run only collects (and pays for) the new listings.
- **Optional export to your apps.** Pipe results into the apps you already use through MCP connectors, with no change to the dataset.

### Use Cases

- **Property researchers and agencies:** track new listings, price changes and open homes across a region.
- **Car buyers and dealers:** monitor Motors listings by make, model, year and odometer to spot good-value vehicles.
- **Marketplace resellers:** watch categories or keyword searches for new stock and Buy Now prices.
- **Recruiters and job seekers:** pull Jobs listings by region, category and salary range.
- **Trust and reputation checks:** pull a seller's feedback score and history before buying from or dealing with them.

### Data You Get

> Sample shape: values are illustrative placeholders, not from a live listing.

| Field | Example |
| --- | --- |
| `vertical` | `"property"` (also `"marketplace"`, `"motors"`, `"jobs"`, `"services"`) |
| `listingId` | `"0000000001"` |
| `title` | `"Sample Listing Title"` |
| `url` | `"https://www.trademe.co.nz/Browse/Listing.aspx?id=0000000001"` |
| `category` | `"Property > Residential > Auckland"` |
| `priceDisplay` | `"$1,234,000"` |
| `startPrice` / `buyNowPrice` | `1234` / `1500` |
| `region` / `suburb` / `district` | `"Auckland"` / `"Sample Suburb"` / `"Sample District"` |
| `photoUrls` | `["https://trademe.tmcdn.co.nz/photoserver/full/000000000.jpg"]` |
| `listedDate` / `closesDate` | `"2026-01-01T00:00:00.000Z"` / `"2026-01-08T00:00:00.000Z"` |
| `sellerType` | `"member"` (also `"dealer"`) |
| `memberId` | `"0000000"` |
| `sellerFeedback` | `{ "uniquePositive": 100, "uniqueNegative": 1, "feedbackPercent": 99, "isSuperSeller": true }` (with full detail on) |
| `bedrooms` / `bathrooms` / `propertyType` | `3` / `2` / `"House"` (Property) |
| `address` | `"1 Example Street, Sample Suburb"` (Property) |
| `agencyName` / `agents` | `"Sample Agency"` / `[{ "name": "Agent Name", "mobilePhone": "+64000000000" }]` (Property; `agents` with full detail on) |
| `make` / `model` / `year` / `odometer` | `"Toyota"` / `"Corolla"` / `2020` / `50000` (Motors) |
| `description` | `"Sample listing description text."` (with full detail on) |
| `scrapedAt` | `"2026-01-01T00:00:00.000Z"` |

Property records also carry land area, floor area, rateable value, latitude and longitude, parking and any open homes; with full detail on they add agency phone, agency website, agency license and a full agency object. Motors records also carry body style, transmission, fuel, exterior colour, 4WD flag, dealer flag and dealer name; with full detail on they add doors, seats, engine size, WOF expiry, registration expiry, owner count and import history. Every listing also carries `price` (the main numeric price), `oldPrice` and `percentageOff` when the listing shows a reduction, `location` (a single readable place string), `primaryImage` and `categoryPath`; Motors and Property records also flag dealer or agency listings, and Motors adds `engineSize`. Any record also carries view count, bidder and watcher count, quantity remaining, shipping options, payment options, store details, a member passthrough object, and the listing's own named specifics (each prefixed `attr_`); `sellerFeedback` additionally carries up to **Max feedback comments** (default 20, 1-500) of the seller's most recent feedback comments when that option is turned on.

### How to Use

1. Pick a section (Marketplace, Property, Motors, Jobs or Services) and a mode: Search (keywords and filters) or URL (paste links).
2. Fill in the filters for that section, and turn on full detail if you want descriptions, the full photo gallery and seller feedback.
3. Set Max items to control how many listings are returned, then click Start.
4. Download the dataset as JSON, CSV or Excel, or read it through the API.

**Search Marketplace by keyword:**

```json
{
  "vertical": "marketplace",
  "mode": "search",
  "queries": ["iphone"],
  "maxItems": 50
}
```

**Search Property with filters and full detail plus seller feedback:**

```json
{
  "vertical": "property",
  "mode": "search",
  "listingType": "residential-sale",
  "region": "auckland",
  "minBedrooms": 3,
  "minPrice": 800000,
  "maxPrice": 1500000,
  "fetchDetails": true,
  "maxItems": 40
}
```

**Search Motors with vehicle filters:**

```json
{
  "vertical": "motors",
  "mode": "search",
  "make": "Toyota",
  "model": "Corolla",
  "minYear": 2015,
  "maxPrice": 20000,
  "maxItems": 30
}
```

**Paste links (category, search or individual listings):**

```json
{
  "mode": "url",
  "startUrls": [
    "https://www.trademe.co.nz/a/property/residential/sale",
    "https://www.trademe.co.nz/a/motors/used-cars"
  ],
  "maxItems": 40
}
```

#### URL shapes

URL mode accepts these link shapes. If you leave **URLs** untouched in URL mode, the actor now scrapes one example of each distinct target below (previously it had no default list). The two listing-id alias forms at the end of the table are pre-filled in the form but resolve to the same listing as the canonical listing link, so they are not part of the untouched default, so set your own links or cap **Max items** to control cost.

| Shape | Example |
|---|---|
| Marketplace keyword search | `https://www.trademe.co.nz/a/marketplace/search?search_string=iphone` |
| Marketplace category | `https://www.trademe.co.nz/a/marketplace/computers/laptops` |
| Property category / listing type | `https://www.trademe.co.nz/a/property/residential/sale` |
| Property paginated (`?page=N`) | `https://www.trademe.co.nz/a/property/residential/sale/auckland?page=2` |
| Motors category | `https://www.trademe.co.nz/a/motors/cars` |
| Jobs search | `https://www.trademe.co.nz/a/jobs/search?search_string=nurse` |
| Services category | `https://www.trademe.co.nz/a/services` |
| Search with sort order | `https://www.trademe.co.nz/a/marketplace/search?search_string=bike&sort_order=PriceAsc` (the link's own sort is used while Sort order is Default) |
| Listing detail | `https://www.trademe.co.nz/a/motors/cars/toyota/aqua/listing/6177402562` |
| Legacy listing link | `https://www.trademe.co.nz/Browse/Listing.aspx?id=6177402562` |
| Listing id only | `https://www.trademe.co.nz/6177402562` |

Links on the `m.trademe.co.nz` host are treated as `www.trademe.co.nz`. Any other link is skipped with a warning in the run log.

#### Output views

The dataset tab has these views: **Listings** (overview with price, old price, location, primary image and key section fields), **Listing details** (description, attributes, agents, shipping and payment, seller feedback summary), **Seller feedback comments** (one column set per feedback comment, with Fetch full details and comments on) and **Changes (incremental)** (change type, changed fields, first and last seen).

#### Run it from your code

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/trademe-co-nz-scraper").call(run_input={"vertical": "property", "mode": "search", "region": "auckland", "maxItems": 40})
for listing in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(listing["title"], listing["priceDisplay"])
```

JavaScript:

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/trademe-co-nz-scraper').call({ vertical: 'property', mode: 'search', region: 'auckland', maxItems: 40 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the **Integrations** tab.

#### How Max pages and Max items shape a walk

Each keyword search or pasted category link walks its own result pages, in the order Trade Me and your Sort order return them, until it runs out of pages, reaches Max pages (if you set one), or reaches its share of Max items, whichever comes first. When a run has several searches or links, each gets a roughly even share of the overall Max items. Leave Max pages empty to walk every result page a search has; the run still stops once Max items is reached.

#### Resume and long-catalogue walks

- **Resume from a previous run** (`resumeFromRunId`) loads every `listingId` already saved in a previous run's dataset before this run starts scraping, so this run only pushes, and only pays for, the new listings. Paste the previous run's ID or its dataset ID. An ID that doesn't match a run or dataset your Apify account can read fails the run immediately, before any scraping, rather than quietly re-collecting everything.
- **Incremental mode** (`incrementalMode`, off by default) is for scheduled runs: it remembers the listings of this exact search scope (or the name you give in `stateKey`) and pushes only what is NEW, UPDATED or REAPPEARED, plus EXPIRED tombstones for listings that disappeared. Each row gets `changeType`, `changedFields`, `firstSeenAt` and `lastSeenAt`. See "Can I run this on a schedule" below. With it off, output is exactly the same as before.
- A checkpoint is saved automatically as the run progresses. If the run is interrupted by an Apify platform migration, or you click **Resurrect** on a failed run, it continues from where it left off in the *same* run, without re-pushing or re-charging for listings it already collected. No input is needed for this; it's automatic.

### Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step **after** the scrape: the Apify dataset is never changed.

**What gets written to the connector:** a condensed, human-readable **summary** of each listing, not the full JSON. Each item becomes one entry with a **title** and its key fields, price, location, category, and section-specific fields such as make and model or bedrooms, flattened to plain text. The **complete record always stays in the Apify dataset**.

1. Authorize a connector once under **Apify, Settings, API & Integrations** (Notion, Linear, Airtable, or Apify).
2. Select it in the **"Pipe results into your apps"** input field. (If the picker is empty, you haven't authorized a connector yet.)
3. For **Notion**, also set `notionParentPageUrl` to the page where items should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

### Input Parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `vertical` | string | `marketplace` | Which section to scrape: Marketplace, Property, Motors, Jobs, or Services. |
| `mode` | string | `search` | `search` (keywords + filters) or `url` (paste links). |
| `queries` | array | none (prefill: `["iphone"]`) | Keyword searches within the section (search mode). Leave empty to browse the whole section or a category. |
| `listingType` | string | `residential-sale` | Property section only: residential-sale, residential-rent, commercial-sale, or lifestyle. |
| `region` | string | none | Property or Jobs section: region name or id (for example auckland, wellington). |
| `district` | string | none | Property or Jobs section: district within the region. |
| `suburb` | string | none | Property section: suburb within the district. |
| `propertyType` | string | none | Property section: for example House, Apartment, Townhouse, Unit, Section, Lifestyle. |
| `minBedrooms` | integer | none | Property section: minimum bedrooms. |
| `maxBedrooms` | integer | none | Property section: maximum bedrooms. |
| `minBathrooms` | integer | none | Property section: minimum bathrooms. |
| `minLandArea` | integer | none | Property section: minimum land area in square metres. |
| `maxLandArea` | integer | none | Property section: maximum land area in square metres. |
| `minFloorArea` | integer | none | Property section: minimum floor area in square metres. |
| `maxFloorArea` | integer | none | Property section: maximum floor area in square metres. |
| `petsOkay` | boolean | `false` | Property section (rentals): only listings that allow pets. |
| `make` | string | none | Motors section: vehicle make, for example Toyota. |
| `model` | string | none | Motors section: vehicle model, for example Corolla. |
| `minYear` | integer | none | Motors section: earliest manufacture year. |
| `maxYear` | integer | none | Motors section: latest manufacture year. |
| `minOdometer` | integer | none | Motors section: minimum odometer reading in km. |
| `maxOdometer` | integer | none | Motors section: maximum odometer reading in km. |
| `bodyStyle` | string | none | Motors section: for example Hatchback, Sedan, SUV, Ute. |
| `transmission` | string | none | Motors section: for example Automatic, Manual. |
| `fuel` | string | none | Motors section: for example Petrol, Diesel, Electric, Hybrid. |
| `category` | string | none | Marketplace, Jobs, or Services section: category id or slug. |
| `condition` | string | `""` (Any) | Marketplace section: item condition, Any, New, or Used. |
| `buyNowOnly` | boolean | `false` | Marketplace section: only listings with a Buy Now price. |
| `jobType` | string | none | Jobs section: for example Full time, Part time, Contract. |
| `minPrice` | integer | none | Minimum price in NZD (minimum salary for Jobs). |
| `maxPrice` | integer | none | Maximum price in NZD (maximum salary for Jobs). |
| `startUrls` | array | one example of each supported link shape (see "URL shapes" below; the prefill adds the two alias forms of the listing link, which resolve to the same listing as the canonical example and so are not run by default) | Category, search, or individual listing links (URL mode). Results continue from the page number already in the URL. |
| `sort` | string | `Default` | Result ordering; which values apply depends on the section. Also orders a pasted category or search URL in URL mode, taking precedence over any ordering already in that URL. |
| `keyword` | string | none | Free-text term used when Keyword searches is empty (it does not combine with Keyword searches). Also applies to a pasted URL, unless that URL already carries its own search term. |
| `fetchDetails` | boolean | `false` | Fetch each listing's full detail page and the seller's member feedback. Adds a per-item detail charge. |
| `includeMemberFeedbackComments` | boolean | `false` | With full detail on, also collect the seller's individual feedback comments. No separate charge: comments ride the listing's existing detail enrichment. |
| `maxFeedbackComments` | integer | `20` | Most recent feedback comments collected per seller (1-500, paged 25 at a time). Earlier versions always returned up to 25; the new default is 20, set 25 to match the old output. |
| `maxItems` | integer | `20` | Maximum number of listings to return. Set `0` for unlimited. |
| `maxPages` | integer | none (walks every result page; `0` has the same effect) | Limit on result pages to walk per search. The run still stops at Max items. |
| `resumeFromRunId` | string | none | A previous run ID or dataset ID to continue an interrupted or paginated walk. Listings already saved there (matched by `listingId`) are skipped. |
| `incrementalMode` | boolean | `false` | Scheduled-run mode: push only NEW, UPDATED, REAPPEARED and EXPIRED listings, with `changeType`, `changedFields`, `firstSeenAt` and `lastSeenAt`. |
| `stateKey` | string | none | Name of the remembered state; by default derived from the search scope. |
| `emitUnchanged` | boolean | `false` | Also push (and pay for) listings that did not change. |
| `emitExpired` | boolean | `true` | Push EXPIRED tombstones for listings that disappeared. |
| `ignoreFieldsForChanges` | array | none | Fields (or dotted paths such as `sellerFeedback.totalCount`) excluded from change detection. |
| `proxy` | object | Apify Proxy enabled | Connection configuration. The default is recommended. |
| `mcpConnectors` | array | none | Optional: send a summary of each listing to apps you authorized under Integrations. |
| `notionParentPageUrl` | string | none | Notion connector only: page under which item pages are created. |
| `maxNotifyListings` | integer | `50` | Cap on items written to each connector per run. Does not affect the dataset. |

### Output Example

> Sample shape: values are illustrative placeholders, not from a live listing.

```json
{
  "vertical": "property",
  "listingId": "0000000001",
  "title": "Sample Listing Title",
  "url": "https://www.trademe.co.nz/Browse/Listing.aspx?id=0000000001",
  "priceDisplay": "$1,234,000",
  "region": "Auckland",
  "suburb": "Sample Suburb",
  "district": "Sample District",
  "address": "1 Example Street, Sample Suburb",
  "bedrooms": 3,
  "bathrooms": 2,
  "propertyType": "House",
  "latitude": -36.0,
  "longitude": 174.0,
  "agencyName": "Sample Agency",
  "agents": [
    { "name": "Agent Name", "mobilePhone": "+64000000000", "email": "agent@example.com" }
  ],
  "memberId": "0000000",
  "sellerFeedback": {
    "nickname": "sample_seller",
    "uniquePositive": 100,
    "uniqueNegative": 1,
    "feedbackPercent": 99,
    "isSuperSeller": true
  },
  "photoUrls": ["https://trademe.tmcdn.co.nz/photoserver/full/000000000.jpg"],
  "scrapedAt": "2026-01-01T00:00:00.000Z"
}
```

### Plan Requirement

The default connection works with no action needed: in testing, the Trade Me data service this actor uses answered the default Apify connection with normal results, so you do not need to pick a residential group. If a connection is refused, the actor rotates to the next one automatically.

On an Apify free plan, residential proxies are not included. If the selected connection is unavailable the log shows:

> The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable.

If every connection is refused, the run fails with: "The proxy connection was refused for this account, so no page could be read. Your Apify plan does not include proxy access; a paid plan is required." If you entered your own proxy URLs, check their credentials. If the backup connection could not load any Trade Me page on a free run, the run reports: "No results: residential proxies are unavailable on this run (Apify free plans do not include them), and the backup connection could not load the requested Trade Me pages."

Any other Apify account with usage credits can run this actor.

### FAQ

#### How much does it cost?

At the current live rates (Free plan): Actor Start $0.08 per run, Listing result $0.002 per listing returned, and Detail enrichment $0.0008 per listing. Paid plans get lower tiered rates; the **Pricing** tab is authoritative. You pay a start fee per run, a fee per listing returned, plus a detail charge for each listing that gains full detail or seller feedback. That happens when you turn on full detail, and always for individual listing links pasted in URL mode, since those are fetched in full so the record is populated. The **Pricing** tab shows the current rates. Use **Max items** to cap the cost of any run.

#### Is it legal to scrape Trade Me?

This actor collects only publicly available marketplace data. You are responsible for how you use it: follow Trade Me's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Prices and listing facts are generally public, but photos and any agency or dealer branding may be subject to third-party rights.

#### Can I run this on a schedule, or only collect new listings?

Yes. Schedule the actor from the **Schedules** tab and switch on **Incremental mode** (`incrementalMode`). The actor then remembers the listings it saw for that exact search scope (or for the **State key** you choose) and each run pushes only:

- `NEW`: a listing not seen before.
- `UPDATED`: a listing whose content changed, with the changed top-level fields in `changedFields`.
- `REAPPEARED`: a listing that had disappeared and is back.
- `EXPIRED`: a tombstone (last known values) for a listing the previous run saw that this search no longer returns. Only produced when the search ran to its natural end starting from page 1; a run that hit Max items, Max pages, a pasted `?page=N` link past page 1, or used Resume is treated as partial and never expires anything. Turn tombstones off with `emitExpired`.
- `UNCHANGED` rows are remembered but not pushed (and not billed) unless you set `emitUnchanged`.

Compared: every output field, including price, Buy Now, closing date, location, photos, category, seller and seller feedback and the vehicle or property attributes. Excluded from the comparison but still in the output: `scrapedAt` and `viewCount` (a page-view counter that moves on every visit; measured on two back-to-back runs of the same search), plus any field you list in **Ignore fields when detecting changes** (`ignoreFieldsForChanges`, a field name or a dotted path such as `sellerFeedback.totalCount`). With Incremental mode on, Max items limits the listings scanned, not only the rows pushed. Billing is unchanged: you pay for the rows that are pushed (and the detail-enrichment surcharge when it applies), nothing for suppressed unchanged listings. The **Changes** view in the dataset tab shows the change columns.

You can still combine this with **Resume from a previous run**; EXPIRED tombstones of that earlier run are ignored when seeding the resume.

#### Why weren't my filters applied when I pasted a URL?

The Search-mode filters (region, price, bedrooms, and so on) only apply in Search mode. In URL mode, a pasted category link is scraped by its category path only: filters in the link's query string, such as price or bedrooms, are not carried over. A pasted keyword-search link runs as a site-wide keyword search on its own search term. Sort order applies to both, and the Extra keyword filter applies when the link has no search term of its own.

#### Why is sellerFeedback missing from my results?

Turn on **Fetch full details + seller feedback**. Without it, you get the search-result fields only. Feedback (positive and negative counts, score, join date) is fetched per listing, and only when that option is on and the listing has a resolvable seller id.

#### Why did my run fail instead of returning an empty dataset?

Only one thing fails the run outright: a **Resume from a previous run** ID that doesn't match a run or dataset your Apify account can read. That check runs before any scraping, so you get a clear error instead of a resume that silently didn't happen. Everything else, an empty category, filters that match nothing, or a search that Trade Me's servers wouldn't answer after several retries, finishes the run normally: that entry contributes no listings (with a warning in the log), while any other keyword search or pasted link in the same run keeps collecting.

#### Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

### 🔗 Want more car data?

Pair this actor with these related scrapers from the same team:

<table>
<tr><td>🏷️ <a href="https://apify.com/abotapi/gumtree-uk-scraper"><b>Gumtree.com Scraper</b></a><br>Scrape Gumtree.com classifieds across motors, property, jobs, services, pets and goods...</td><td>🏷️ <a href="https://apify.com/abotapi/subito-it-scraper"><b>Subito.it Scraper</b></a><br>Scrape Subito.it listings across cars, real estate, marketplace, jobs, and more. Search...</td></tr>
<tr><td>🏷️ <a href="https://apify.com/abotapi/kijiji-scraper"><b>Kijiji.ca Scraper</b></a><br>Scrape Kijiji.ca listings across property, vehicles, jobs, electronics, furniture...</td><td>🏷️ <a href="https://apify.com/abotapi/gumtree-au-scraper"><b>Gumtree AU Scraper</b></a><br>Scrape gumtree.com.au classifieds across every vertical: for-sale goods, motors, real...</td></tr>
<tr><td>🚗 <a href="https://apify.com/abotapi/willhaben-at-scraper"><b>Willhaben.at Scraper</b></a><br>From $1/1K. Scrape Willhaben.at listings into clean JSON with 40+ structured fields...</td><td>🚗 <a href="https://apify.com/abotapi/carsales-au-scraper"><b>Carsales.com.au Scraper</b></a><br>Scrape structured vehicle listings from Carsales.com.au from $1 per 1K results. Built to...</td></tr>
</table>

👉 [Browse all abotapi scrapers](https://apify.com/abotapi)

### 💬 Support

- 🐞 **Found a bug or a missing field?** Open a ticket on the [Issues tab](https://apify.com/abotapi/trademe-co-nz-scraper/issues/open). We usually reply within hours.
- 🛠️ **Need another site, extra fields or a private build?** Email <contact@abotapi.com>.
- ⭐ **Enjoying it?** A quick review on the actor page helps other users find it.

# Actor input Schema

## `vertical` (type: `string`):

Which Trade Me section to scrape: Marketplace (general goods and auctions), Property, Motors (vehicles), Jobs, or Services.

## `mode` (type: `string`):

Search mode uses keywords and filters. URL mode scrapes category, search or individual listing links you paste.

## `queries` (type: `array`):

One or more keyword searches within the selected section (for example: iphone, mountain bike). Leave empty to browse the whole section or a category.

## `listingType` (type: `string`):

Property section only. Which property market to search.

## `region` (type: `string`):

Property or Jobs section. Region name or id (for example: auckland, wellington, canterbury).

## `district` (type: `string`):

Property or Jobs section. District within the region.

## `suburb` (type: `string`):

Property section. Suburb within the district.

## `propertyType` (type: `string`):

Property section. For example: House, Apartment, Townhouse, Unit, Section, Lifestyle.

## `minBedrooms` (type: `integer`):

Property section. Minimum number of bedrooms.

## `maxBedrooms` (type: `integer`):

Property section. Maximum number of bedrooms.

## `minBathrooms` (type: `integer`):

Property section. Minimum number of bathrooms.

## `minLandArea` (type: `integer`):

Property section. Minimum land area in square metres.

## `maxLandArea` (type: `integer`):

Property section. Maximum land area in square metres.

## `minFloorArea` (type: `integer`):

Property section. Minimum floor area in square metres.

## `maxFloorArea` (type: `integer`):

Property section. Maximum floor area in square metres.

## `petsOkay` (type: `boolean`):

Property section (rentals). Only listings that allow pets.

## `make` (type: `string`):

Motors section. For example: Toyota, Ford, Mazda.

## `model` (type: `string`):

Motors section. For example: Corolla, Ranger.

## `minYear` (type: `integer`):

Motors section. Earliest manufacture year.

## `maxYear` (type: `integer`):

Motors section. Latest manufacture year.

## `minOdometer` (type: `integer`):

Motors section. Minimum odometer reading.

## `maxOdometer` (type: `integer`):

Motors section. Maximum odometer reading.

## `bodyStyle` (type: `string`):

Motors section. For example: Hatchback, Sedan, SUV, Ute.

## `transmission` (type: `string`):

Motors section. For example: Automatic, Manual.

## `fuel` (type: `string`):

Motors section. For example: Petrol, Diesel, Electric, Hybrid.

## `category` (type: `string`):

Marketplace, Jobs or Services section. Category id or slug to narrow the search.

## `condition` (type: `string`):

Marketplace section. Item condition.

## `buyNowOnly` (type: `boolean`):

Marketplace section. Only listings with a Buy Now price.

## `jobType` (type: `string`):

Jobs section. For example: Full time, Part time, Contract.

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

Minimum price in NZD (or minimum salary for Jobs).

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

Maximum price in NZD (or maximum salary for Jobs).

## `startUrls` (type: `array`):

Trade Me category, search-result or individual listing URLs. Results continue from the page number in the URL onward.

## `sort` (type: `string`):

Result ordering. Applicability varies by section: Marketplace supports Default, FeaturedFirst, PriceAsc, PriceDesc, TitleAsc, ExpiryAsc, ExpiryDesc, BidsMost, BuyNowPrice; Jobs supports BestMatch, JobsLatestListingDesc, HighestSalary, LowestSalary; Services supports ReviewsDesc. Also orders a pasted category or search URL in URL mode, taking precedence over any ordering already encoded in that URL. Leave as Default if unsure.

## `keyword` (type: `string`):

Optional free-text term applied on top of the section and filters. Also applies to a pasted URL in URL mode, but only when that URL does not already contain a search term of its own, in which case the URL's own term wins.

## `fetchDetails` (type: `boolean`):

Fetch each listing's full detail page and the seller's member feedback (positive/negative counts and score). Slower and adds a per-item detail charge.

## `includeMemberFeedbackComments` (type: `boolean`):

When full details are enabled, also collect the seller's individual feedback comments.

## `maxFeedbackComments` (type: `integer`):

With feedback comments on, the most recent comments to collect for each seller (paged 25 at a time). Previously the actor always returned up to 25.

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

Maximum number of listings to return. This is the main limit. Set 0 for unlimited.

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

Limit on result pages to walk per search. Leave empty to walk every result page; the run still stops at Max items.

## `proxy` (type: `object`):

Connection configuration. The default is recommended.

## `resumeFromRunId` (type: `string`):

Paste a previous run ID or dataset ID to continue an interrupted or paginated walk. Listings already collected there (matched by listingId) are skipped, so this run only saves the new ones. Leave empty for a normal fresh run.

## `incrementalMode` (type: `boolean`):

ON: the actor remembers the listings it saw for this exact search scope (keyed automatically, or use State key) and on each scheduled run marks every listing NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED, pushing only new and changed rows plus EXPIRED tombstones, and stamping each row with changeType, changedFields, firstSeenAt and lastSeenAt. COMPARED: every output field (title, prices, Buy Now, closing date, location, photos, category, seller and seller feedback, vehicle/property attributes). EXCLUDED from the comparison but still in the output: scrapedAt and viewCount (a page-view counter that moves on every visit), plus anything you list under Ignore fields. EXPIRED rows are only produced when the search ran to its natural end from page 1 (not for a capped, Max pages-limited, resumed or ?page=N>1 run). With Incremental mode ON, Max items limits the listings scanned. OFF (default): every run returns the full result set, unchanged.

## `stateKey` (type: `string`):

Name of the incremental baseline when Incremental mode is ON. Leave empty to key it automatically on a hash of the search scope (recommended). Reuse the same key across runs to compare like with like; a different key starts a new baseline.

## `emitUnchanged` (type: `boolean`):

With Incremental mode ON, also push listings that did not change (changeType UNCHANGED). Default OFF: unchanged listings are remembered but not pushed, and not billed.

## `emitExpired` (type: `boolean`):

With Incremental mode ON, push a tombstone row (changeType EXPIRED, last known values) for listings the previous run saw that this run's search no longer returns - only when the search ran to completion. Default ON.

## `ignoreFieldsForChanges` (type: `array`):

With Incremental mode ON, output fields listed here never count as a change (they are excluded from changeType and changedFields while staying in the output). Use a field name (photoUrls) or a dotted path for a nested field (sellerFeedback.totalCount). Built-in defaults already cover scrapedAt and viewCount.

## `mcpConnectors` (type: `array`):

Optionally send results into apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a page per item; other connectors get a best-effort write. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL or id of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "vertical": "marketplace",
  "mode": "search",
  "queries": [
    "iphone"
  ],
  "listingType": "residential-sale",
  "petsOkay": false,
  "condition": "",
  "buyNowOnly": false,
  "startUrls": [
    "https://www.trademe.co.nz/a/marketplace/search?search_string=iphone",
    "https://www.trademe.co.nz/a/marketplace/computers/laptops",
    "https://www.trademe.co.nz/a/property/residential/sale",
    "https://www.trademe.co.nz/a/property/residential/sale/auckland?page=2",
    "https://www.trademe.co.nz/a/motors/cars",
    "https://www.trademe.co.nz/a/jobs/search?search_string=nurse",
    "https://www.trademe.co.nz/a/services",
    "https://www.trademe.co.nz/a/marketplace/search?search_string=bike&sort_order=PriceAsc",
    "https://www.trademe.co.nz/a/motors/cars/toyota/aqua/listing/6177402562",
    "https://www.trademe.co.nz/Browse/Listing.aspx?id=6177402562",
    "https://www.trademe.co.nz/6177402562"
  ],
  "sort": "Default",
  "fetchDetails": false,
  "includeMemberFeedbackComments": false,
  "maxFeedbackComments": 20,
  "maxItems": 20,
  "proxy": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": true,
  "ignoreFieldsForChanges": [],
  "maxNotifyListings": 50
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `detail` (type: `string`):

No description

## `feedback` (type: `string`):

No description

## `changes` (type: `string`):

No description

## `summary` (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 = {
    "mode": "search",
    "queries": [
        "iphone"
    ],
    "startUrls": [
        "https://www.trademe.co.nz/a/marketplace/search?search_string=iphone",
        "https://www.trademe.co.nz/a/marketplace/computers/laptops",
        "https://www.trademe.co.nz/a/property/residential/sale",
        "https://www.trademe.co.nz/a/property/residential/sale/auckland?page=2",
        "https://www.trademe.co.nz/a/motors/cars",
        "https://www.trademe.co.nz/a/jobs/search?search_string=nurse",
        "https://www.trademe.co.nz/a/services",
        "https://www.trademe.co.nz/a/marketplace/search?search_string=bike&sort_order=PriceAsc",
        "https://www.trademe.co.nz/a/motors/cars/toyota/aqua/listing/6177402562",
        "https://www.trademe.co.nz/Browse/Listing.aspx?id=6177402562",
        "https://www.trademe.co.nz/6177402562"
    ],
    "proxy": {
        "useApifyProxy": true
    },
    "ignoreFieldsForChanges": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/trademe-co-nz-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 = {
    "mode": "search",
    "queries": ["iphone"],
    "startUrls": [
        "https://www.trademe.co.nz/a/marketplace/search?search_string=iphone",
        "https://www.trademe.co.nz/a/marketplace/computers/laptops",
        "https://www.trademe.co.nz/a/property/residential/sale",
        "https://www.trademe.co.nz/a/property/residential/sale/auckland?page=2",
        "https://www.trademe.co.nz/a/motors/cars",
        "https://www.trademe.co.nz/a/jobs/search?search_string=nurse",
        "https://www.trademe.co.nz/a/services",
        "https://www.trademe.co.nz/a/marketplace/search?search_string=bike&sort_order=PriceAsc",
        "https://www.trademe.co.nz/a/motors/cars/toyota/aqua/listing/6177402562",
        "https://www.trademe.co.nz/Browse/Listing.aspx?id=6177402562",
        "https://www.trademe.co.nz/6177402562",
    ],
    "proxy": { "useApifyProxy": True },
    "ignoreFieldsForChanges": [],
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/trademe-co-nz-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 '{
  "mode": "search",
  "queries": [
    "iphone"
  ],
  "startUrls": [
    "https://www.trademe.co.nz/a/marketplace/search?search_string=iphone",
    "https://www.trademe.co.nz/a/marketplace/computers/laptops",
    "https://www.trademe.co.nz/a/property/residential/sale",
    "https://www.trademe.co.nz/a/property/residential/sale/auckland?page=2",
    "https://www.trademe.co.nz/a/motors/cars",
    "https://www.trademe.co.nz/a/jobs/search?search_string=nurse",
    "https://www.trademe.co.nz/a/services",
    "https://www.trademe.co.nz/a/marketplace/search?search_string=bike&sort_order=PriceAsc",
    "https://www.trademe.co.nz/a/motors/cars/toyota/aqua/listing/6177402562",
    "https://www.trademe.co.nz/Browse/Listing.aspx?id=6177402562",
    "https://www.trademe.co.nz/6177402562"
  ],
  "proxy": {
    "useApifyProxy": true
  },
  "ignoreFieldsForChanges": []
}' |
apify call abotapi/trademe-co-nz-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/trademe-co-nz-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/v93a6Tjuecga6BbH6/builds/1uBjl9OZz5R1Mw5pG/openapi.json
