# Tori Scraper — Listings, Prices, Sellers & GPS (`haketa/tori-scraper`) Actor

Scrape Tori.fi, Finland's largest classifieds, by keyword or URL. Get price (EUR), seller type (private/retailer), location with GPS, publish date, brand, attributes, photos and the full ad description. Cars, electronics, home and more. No API key. Export JSON, CSV, Excel.

- **URL**: https://apify.com/haketa/tori-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** E-commerce, Lead generation
- **Features:** Limited permissions
- **Stats:** 3 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 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?

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

## Tori.fi Scraper — Listings, Prices, Seller Type, GPS & Photos 🇫🇮

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-orange?logo=apify)](https://apify.com/haketa/tori-scraper)
[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://apify.com/haketa/tori-scraper)
[![Data Format](https://img.shields.io/badge/Data-JSON%20%7C%20CSV%20%7C%20Excel-blue)](#-output)
[![Pagination](https://img.shields.io/badge/Pagination-1%2C000%2B%20Unlocked-brightgreen)](#-pagination--scale)
[![Proxy Support](https://img.shields.io/badge/Proxy-Datacenter-success)](#-input)

> **Scrape [Tori.fi](https://www.tori.fi), Finland's largest classifieds marketplace, at scale — without an account, cookies or API key.** This **Tori scraper** turns any keyword or search URL into a clean, structured dataset: **price in EUR, seller type (private vs retailer), location with GPS coordinates, publish date, brand, category attributes, the full photo gallery — and the complete ad description** with optional detail enrichment.

Export every result to **JSON, CSV, Excel, or API**.

> Built for resellers and flippers sourcing second-hand inventory, sales teams building Finnish retailer lead lists, price and market analysts tracking the Finnish used market, automotive data teams, and developers who need reliable Tori.fi data through an API.

***

### ⚡ At a glance

| Feature | Details |
| :--- | :--- |
| **Target Website** | [tori.fi](https://www.tori.fi) (Finland #1 Classifieds & Secondhand) |
| **Search Capabilities** | Keywords, custom search URLs, categories, price range, seller types |
| **Pagination Limit** | **1,000+ Unlocked** (`maxPagesPerSearch: 0` for auto/unlimited deep pagination) |
| **Pricing & Currency** | Clean numeric prices in Euro (EUR) |
| **Seller Identification** | Clear segmentation between `private` sellers and commercial `retailer` dealers |
| **Geo & Logistics** | Full city/neighbourhood names, exact GPS coordinates (`lat`/`lng`), shipping flags |
| **Proxy Requirement** | Datacenter Proxy (Apify Proxy included by default) |
| **Average Speed** | ~50 listings per second (~500 listings in ~20–30 seconds) |
| **Output Formats** | JSON, CSV, Excel (XLSX), XML, HTML Table, RSS |

***

### 🔎 Why scrape Tori.fi?

**Tori.fi** (formerly part of Schibsted / Qasa, now Adevinta) is the dominant second-hand marketplace in Finland — millions of live listings for cars, electronics, furniture, home goods, fashion, tools, bikes, boats and more. Every listing is a tiny, real-time signal about what things sell for in Finland, who is selling (a private person or a commercial dealer), and where in the country supply is concentrated.

That makes **Tori.fi data** extremely valuable: it is the ground truth for Finnish second-hand pricing, resale and arbitrage opportunities, competitive retailer intelligence, and consumer demand research. But collecting it by hand is painful — the site paginates endlessly, prices and seller types are buried in cards, there is no public bulk export, and listings refresh constantly so any manual snapshot is stale within hours.

This **Tori.fi scraper** does the collecting for you. Point it at a keyword or a search URL and it paginates automatically, de-duplicates by listing ID, and returns hundreds-to-thousands of normalized records with typed fields you can drop straight into a spreadsheet, database or model.

**Common reasons people scrape Tori.fi:**

- 💰 **Price research** — build a live dataset of what any product sells for across Finland.
- 🔁 **Reselling, flipping & arbitrage** — find underpriced phones, consoles, furniture, bikes and car parts.
- 🎯 **Lead generation** — isolate **retailers / dealers** to build commercial lead lists in your niche.
- 📈 **Market monitoring** — track supply, average price and seller mix week over week.
- 🚗 **Automotive & valuation data** — capture used-car titles, prices, brand, location and coordinates.
- 🗺️ **Geographic analysis** — map supply by region using per-listing GPS coordinates.
- 🤖 **AI / LLM pipelines** — feed clean, structured classifieds data into RAG, dashboards and data products.

***

### ✨ What this Tori.fi scraper does

- 🔎 **Search by keyword** — `iphone`, `volvo v70`, `sohva`, `polkupyörä` — any term, across every Tori category. Add several terms and results are combined and de-duplicated automatically.
- 🔗 **Or scrape search URLs directly** — paste any Tori search page (category, brand, price band, region) and the query filters in the URL are preserved.
- 🔁 **Unlocked 1,000+ deep pagination** — walks through search result pages past the old 50-page boundary without artificial limits.
- 💰 **Prices in EUR** — the exact numeric amount plus currency, ready for analysis.
- 👤 **Seller type** — every listing is flagged **`private`** or **`retailer`** — the key field for lead generation and for separating hobby sellers from commercial dealers.
- 📍 **Location + GPS** — the place name plus exact **latitude/longitude** coordinates for every listing.
- 🕒 **Publish date** — the real ISO timestamp each ad went live.
- 🏷️ **Brand & attributes** — brand plus category-specific fields (storage size, memory, model and more) where the listing provides them.
- 🚚 **Listing signals** — boolean flags for **shippable**, **buy-now (Osta heti)** and **seller pays shipping**.
- 🖼️ **Full photo gallery** — the main image plus every image URL on the listing.
- 📝 **Full ad description** — enable **Fetch full descriptions** to open each listing and capture its complete description text.
- ⚡ **Fast & reliable** — runs over the public Tori search JSON API with automatic retries and proxy rotation.
- 📤 **Any export** — JSON, CSV, Excel, HTML, RSS or the Apify API.

***

### 🎯 Use cases

- **Resellers & flippers** sourcing second-hand phones, consoles, furniture and bikes below market price.
- **Sales & growth teams** building Finnish lead lists of active **retailers** in a niche.
- **Pricing & market analysts** benchmarking the live Finnish second-hand market and tracking trends over time.
- **Automotive dealers & valuation tools** capturing used-car prices, brand, location and coordinates.
- **E-commerce & inventory teams** monitoring competitor stock, price and seller mix.
- **Researchers & data teams** assembling structured classifieds datasets for analysis.
- **Developers & AI builders** who need clean, de-duplicated **Tori.fi data** through an API or MCP server.
- **Geo / supply analysts** mapping where listings for a product concentrate across Finland.

***

### 📥 Input parameters

Configure the scraper with a few simple fields — no code required. Enter one or more **Search Terms**, or paste **Start URLs**, then optionally filter by seller type and price.

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `searchTerms` | Array | `["iphone"]` | Keywords to search, e.g. `"iphone"`, `"volvo v70"`, `"sohva"`. Each term is searched separately. Leave empty if you use Start URLs. |
| `startUrls` | Array | `[]` | Optional. Full Tori search URLs to scrape directly (a specific search, category, brand or price range). The query filters in the URL are carried over. |
| `sellerType` | Select | `""` (any) | Filter results: `""` (any), `"private"`, or `"retailer"`. Ideal for commercial lead generation. |
| `priceMin` | Integer | None | Keep only listings at or above this price (EUR). |
| `priceMax` | Integer | None | Keep only listings at or below this price (EUR). |
| `maxItems` | Integer | `0` (unlimited) | Max total listings to collect across all searches. `0` = unlimited. Prefill is set to `100` for rapid testing. |
| `maxPagesPerSearch` | Integer | `0` (unlimited) | How many result pages to scrape per term / URL (`0` = auto/unlimited governed by `maxItems`). Each page holds about 50 listings. |
| `fetchDetails` | Boolean | `false` | Open each listing to also capture its full ad description. Slower — leave off for fast, low-cost list scraping. |
| `proxyConfiguration` | Object | `{ "useApifyProxy": true }` | Proxy settings. The default (Apify Proxy, datacenter) works out of the box. |

#### Example input configuration

```json
{
  "searchTerms": ["macbook pro", "thinkpad"],
  "sellerType": "private",
  "priceMin": 200,
  "priceMax": 1200,
  "maxItems": 250,
  "maxPagesPerSearch": 0,
  "fetchDetails": false,
  "proxyConfiguration": { "useApifyProxy": true }
}
```

***

### 📤 Output dataset

Every listing is normalized into a consistent, flat JSON object with typed fields.

#### Sample output item

```json
{
  "id": "49355593",
  "url": "https://www.tori.fi/recommerce/forsale/item/49355593",
  "title": "Apple iPhone 16 E 64 Gt",
  "price": 350,
  "currency": "EUR",
  "tradeType": "Myydään",
  "sellerType": "private",
  "location": "Jyväskylä Keskus, Jyväskylä",
  "lat": 62.24114,
  "lng": 25.75672,
  "publishedDate": "2026-11-02T00:17:58.000Z",
  "brand": "Apple",
  "isShippable": true,
  "sellerPaysShipping": false,
  "canBuyNow": false,
  "labels": ["ToriDiili", "Yksityinen"],
  "imageUrl": "https://img.tori.net/dynamic/default/item/49355593/d88bb456-....jpg",
  "images": [
    "https://img.tori.net/dynamic/default/item/49355593/d88bb456-....jpg",
    "https://img.tori.net/dynamic/default/item/49355593/00edcc66-....jpg"
  ],
  "attributes": { "memory_size": "64 GB", "brand": "Apple" },
  "description": null,
  "searchTerm": "iphone",
  "scrapedAt": "2026-11-10T12:58:00.000Z"
}
```

***

#### Field reference

| Field | Type | Coverage | Description |
| :--- | :--- | :--- | :--- |
| `id` | String | 🟢 High (100%) | Unique Tori listing ID (natural key, used for de-duplication). |
| `url` | String | 🟢 High (100%) | Direct canonical link to the listing. |
| `title` | String | 🟢 High (100%) | Ad title. |
| `price` | Integer | 🟢 High (100%) | Price in EUR (number). |
| `currency` | String | 🟢 High (100%) | Currency code — always `EUR`. |
| `tradeType` | String | 🟢 High (100%) | Whether the ad is selling (`Myydään`) or wanted (`Ostetaan`). |
| `sellerType` | String | 🟢 High (100%) | `private` or `retailer` — the key field for lead generation. |
| `location` | String | 🟢 High (100%) | Place name shown on the ad (neighbourhood + city). |
| `lat` | Float | 🟢 High (100%) | Latitude GPS coordinate. |
| `lng` | Float | 🟢 High (100%) | Longitude GPS coordinate. |
| `publishedDate` | String | 🟢 High (100%) | When the ad was published (ISO 8601 timestamp). |
| `brand` | String | 🟡 Conditional (75%) | Brand — present when the listing provides one (data-dependent). |
| `isShippable` | Boolean | 🟢 High (100%) | `true` if the seller offers postal shipping. |
| `sellerPaysShipping` | Boolean | 🟢 High (100%) | `true` if the seller covers shipping costs. |
| `canBuyNow` | Boolean | 🟢 High (100%) | `true` if buy-now (`Osta heti`) is active. |
| `labels` | Array | 🟢 High (90%) | Listing labels shown on the card (e.g. `ToriDiili`, `Yksityinen`). |
| `imageUrl` | String | 🟢 High (99%) | Primary hero image URL. |
| `images` | Array | 🟢 High (99%) | Array of all gallery photo URLs for the ad. |
| `attributes` | Object | 🟡 Conditional (75%) | Structured category fields (memory, storage, model, etc.). |
| `description` | String | 🟡 Conditional | Full text ad description (populated when `fetchDetails` is on). |
| `searchTerm` | String | 🟢 High (100%) | The search keyword or phrase that produced this result. |
| `scrapedAt` | String | 🟢 High (100%) | ISO 8601 UTC timestamp of data extraction. |

***

### 📊 Comparison: Why use this Actor?

| Feature | Manual Browsing | Custom Scraper | Tori Scraper |
| :--- | :--- | :--- | :--- |
| **Data Source** | Web DOM HTML parsing | Fragile CSS selectors | **Fast Recommerce JSON API** |
| **Seller Segmentation** | Manual inspection | Unclear tags | **Clean `private` vs `retailer` flags** |
| **GPS Coordinates** | Not visible in UI | Requires map reverse lookup | **Exact `lat`/`lng` on every row** |
| **Deep Pagination** | Capped at 50 pages | Often breaks on offsets | **1,000+ Unlocked** (`maxPages: 0`) |
| **Currency Consistency** | Mixed notations | Unstandardized | **Strict EUR numerical parsing** |
| **Anti-Bot Resilience** | Session cookies required | Fails on cookie expiration | **Automatic session warm-up** |

***

### 💻 Developer & API integrations

You can trigger this actor and retrieve structured classifieds datasets programmatically using Apify's API clients or cURL.

#### Python integration

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run_input = {
    "searchTerms": ["polkupyörä", "sähköpyörä"],
    "sellerType": "private",
    "priceMin": 100,
    "priceMax": 800,
    "maxItems": 300,
    "maxPagesPerSearch": 0,
}

run = client.actor("haketa/tori-scraper").call(run_input=run_input)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"[{item['sellerType']}] {item['title']} - €{item['price']} ({item['location']})")
```

#### Node.js integration

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const input = {
    searchTerms: ['sohva', 'nojatuoli'],
    maxItems: 200,
    maxPagesPerSearch: 0,
};

const run = await client.actor('haketa/tori-scraper').call(input);
const { items } = await client.dataset(run.defaultDatasetId).listItems();

console.log(`Extracted ${items.length} Finnish secondhand listings.`);
items.forEach(i => console.log(`${i.title}: €${i.price} [${i.location}]`));
```

#### cURL API call

```bash
curl "https://api.apify.com/v2/acts/haketa~tori-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "searchTerms": ["playstation 5"],
    "maxItems": 100,
    "maxPagesPerSearch": 0
  }'
```

***

#### Analyzing Tori.fi listings with Python & pandas

```python
import pandas as pd
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
dataset_items = client.dataset("DATASET_ID").list_items().items

df = pd.DataFrame(dataset_items)

## Price summary in EUR
valid_prices = df['price'].dropna()
print(f"Total listings: {len(df)}")
print(f"Median price: €{valid_prices.median():.2f}")
print(f"Average price: €{valid_prices.mean():.2f}")

## Seller type distribution
print("\nSeller breakdown:")
print(df['sellerType'].value_counts())

## Top geographic hubs
print("\nTop 5 listing locations:")
print(df['location'].value_counts().head(5))
```

***

### ⚙️ How to use Tori Scraper

1. **Open the Actor in Apify Console**: Go to `haketa/tori-scraper` on the Apify Store or Console.
2. **Specify Keywords or URLs**: Enter keywords in `searchTerms` (e.g. `iphone`, `marimekko`) or paste custom search URLs into `startUrls`.
3. **Filter by Seller or Price**: Select `private` or `retailer` if segmenting leads, and specify min/max price bounds if relevant.
4. **Configure Pagination**: Keep `maxPagesPerSearch: 0` to enable full pagination up to your `maxItems` target.
5. **Run**: Click **Start**. The actor extracts items at ~50 listings per second and updates live progress in the console.
6. **Export Your Dataset**: Download clean structured results in CSV, Excel, JSON, or connect via webhook to your database.

***

### 🔁 Pagination & scale

The scraper calls the public Tori **search JSON API** and walks the result **pages** automatically — `page=1, 2, 3, …` — reading the real `last` page from the API's own paging metadata so it never over- or under-requests.

- **Set `maxPagesPerSearch: 0` for auto-pagination**: Leaving `maxPagesPerSearch: 0` removes artificial page limits, continuing until `maxItems` is met or all matching ads are collected.
- **Cross-term query expansion**: If an explicit `maxItems >= 1000` is requested, the actor automatically expands across popular Finnish marketplace categories to ensure large targets are reached.
- **Strict Deduplication**: Every record is de-duplicated by its unique listing `id` across all search terms and URLs, guaranteeing 0 duplicate items.

***

### 💡 Pro tips for best results

- **Filter commercial dealers** — Use `sellerType: "retailer"` to extract B2B lead lists of stores and dealerships operating in Finland.
- **Find secondhand bargains** — Use `sellerType: "private"` and set `priceMax` to filter out overpriced commercial listings.
- **Map regional supply** — Every row has accurate `lat` and `lng` coordinates. Export to CSV or GeoJSON to map demand density across Finnish municipalities.
- **Keep runs fast** — Leave `fetchDetails: false` unless you specifically require long description paragraphs; list data already contains price, location, brand, attributes, and photos.

***

### ⚠️ Limitations & considerations

- **Listing Availability**: Tori.fi items are sold and removed rapidly. Historical prices reflect what items were listed for at scrape time.
- **Language**: Listing titles and descriptions are in Finnish (or Swedish in Swedish-speaking regions of Finland).
- **Detail Enrichment**: Enabling `fetchDetails` requires loading individual HTML pages, which increases total run time.

***

### ❓ Frequently Asked Questions

**How does pagination work past 1,000 items?**
With `maxPagesPerSearch: 0`, the scraper requests consecutive pages of 50 listings each until `maxItems` is satisfied or all matching items are exhausted.

**Do I need a Tori account or login?**
No account or login is required. The actor reads from public listing APIs.

**In what currency are prices reported?**
All prices are parsed as numbers in Euro (EUR), the official currency of Finland.

**Can I scrape by category or region?**
Yes. You can build any category, price, or regional filter on tori.fi, copy the address-bar URL, and paste it into `startUrls`.

**What export formats are supported?**
JSON, CSV, Excel (XLSX), XML, and RSS feeds, plus direct programmatic integration with Apify REST APIs.

***

### 🔗 Related scrapers

- [DBA.dk Scraper — Denmark Classifieds & Prices](https://apify.com/haketa/dba-scraper)
- [Finn.no Scraper — Norway Classifieds & Real Estate](https://apify.com/haketa/finn-scraper)
- [Blocket Scraper — Sweden Secondhand Marketplace](https://apify.com/haketa/blocket-scraper)
- [Marktplaats.nl Scraper — Netherlands Classifieds](https://apify.com/haketa/marktplaats-scraper)
- [Kleinanzeigen.de Scraper — Germany Classifieds](https://apify.com/haketa/kleinanzeigen-scraper)

***

### 📋 Changelog

#### Version 1.2 (2026-11)

- **Unlocked 1,000+ Pagination**: Set `maxPagesPerSearch` default to `0` (auto/unlimited, governed by `maxItems`) and removed artificial 50-page ceilings.
- **Standardized EUR Pricing**: Confirmed clean numeric extraction and currency standardization in Euro.
- **Fast Prefill Performance**: Streamlined default 100-item prefill runs to finish in ~15–20 seconds over datacenter proxies.
- **Schema & Documentation Update**: Added detailed field coverage indicators, comparison tables, and multi-language API integration examples.

#### Version 1.1 (2026-09)

- Added automatic cookie warm-up for persistent search API connectivity.
- Added query parameter preservation from custom `startUrls`.

#### Version 1.0 (2026-08)

- Initial release with keyword search, seller type filtering, GPS coordinates, and photos.

# Changelog

This Actor's version history is a separate document: https://apify.com/haketa/tori-scraper/changelog.md

# Actor input Schema

## `searchTerms` (type: `array`):

What to search for, e.g. 'iphone', 'volvo v70', 'sofa'. Each term is searched separately. Leave empty if you use Start URLs.

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

Optional. Paste full Tori search URLs to scrape them directly (a specific search, category, brand, price range, etc.). When provided, Search Terms below are ignored for these URLs.

## `sellerType` (type: `string`):

Filter by private sellers or retailers/dealers (useful for lead generation and separating hobby sellers from commercial ones).

## `priceMin` (type: `integer`):

Only listings at or above this price.

## `priceMax` (type: `integer`):

Only listings at or below this price.

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

Maximum number of listings to collect across all searches. 0 = unlimited.

## `maxPagesPerSearch` (type: `integer`):

How many result pages to scrape per search term / URL (0 = auto/unlimited governed by Max Items). Each page has about 50 listings.

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

Visit each listing to also collect its full ad description. This is slower and uses more resources — leave off for fast, low-cost list scraping.

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

Proxy settings. The default (Apify Proxy, datacenter) works out of the box. If IPs ever get throttled, switch to Residential and country Finland.

## Actor input object example

```json
{
  "searchTerms": [
    "iphone"
  ],
  "startUrls": [],
  "sellerType": "",
  "maxItems": 100,
  "maxPagesPerSearch": 0,
  "fetchDetails": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

Open to view and export all scraped listings (JSON, CSV, Excel).

# 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 = {
    "searchTerms": [
        "iphone"
    ],
    "startUrls": [],
    "maxItems": 100,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/tori-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 = {
    "searchTerms": ["iphone"],
    "startUrls": [],
    "maxItems": 100,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/tori-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 '{
  "searchTerms": [
    "iphone"
  ],
  "startUrls": [],
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call haketa/tori-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,haketa/tori-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/hB1V47yyeVFfi2GLW/builds/jexPXkin6hSeYTbRq/openapi.json
