# Subito.it Search Scraper (`axery/subito-it-search-scraper`) Actor

Search Subito.it classified ads by keyword across any category, region, or ad type.

- **URL**: https://apify.com/axery/subito-it-search-scraper.md
- **Developed by:** [Axery](https://apify.com/axery) (community)
- **Categories:** E-commerce, Automation, Integrations
- **Stats:** 2 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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

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

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

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

# README

## Subito.it Search Scraper

Turn Italy's biggest classifieds marketplace into a clean, analysis-ready dataset. Search [Subito.it](https://www.subito.it) by keyword across any category, region, or ad type — and get back structured JSON you can load straight into a spreadsheet, database, or pricing model.

**No browser. No login. No CAPTCHA solving.** Pure HTTP, which means it runs fast and cheap.

### What makes this different

Most scrapers hand you raw HTML scrapings or the site's internal blob and leave the cleanup to you. This one does the cleanup:

| | Raw Subito data | What this Actor gives you |
|---|---|---|
| **Price** | `"289"` (string, buried in a nested feature map) | `289` — a real number, ready to sort, filter, and average |
| **Shipping cost** | `"0,99"` (Italian comma decimal) | `0.99` — correctly parsed float |
| **Date** | `"2026-08-22 11:24:41"` (no timezone) | `"2026-08-22T11:24:41+02:00"` — ISO-8601, parseable anywhere |
| **Images** | CDN URLs that return **HTTP 400** | Working URLs, plus matching thumbnails |
| **Car mileage** | `"29"` (an opaque bucket index) | `"180.000 - 189.999"` **and** `mileage_scalar: 182000` |
| **Attributes** | 40+ nested objects keyed `/item_condition` | Flat `attributes` map with readable keys and typed values |
| **Seller** | `type: 1`, `company: true` | `sellerType: "company"` + `shopName` |

Every row is flat, typed, and consistent — whatever category you scrape.

### What you can build with it

- **Price intelligence** — track asking prices for any product across Italy, by region, condition, or seller type. `price` is numeric, so aggregation is immediate.
- **Deal sourcing** — surface underpriced listings the moment they appear; sort by `publishedAt` and filter on `condition` and `shippable`.
- **Market supply analysis** — measure inventory depth by category and province, and split private sellers from professional dealers with one field (`sellerType`).
- **Dealer monitoring** — group by `sellerId` / `shopName` to watch a competitor's full inventory and pricing moves.
- **Product research & resale** — pull real second-hand transaction supply for electronics, cars, furniture, or real estate.
- **AI / ML training data** — Italian-language product descriptions paired with prices, categories, condition labels, and working image URLs.

### Features

- **Whole marketplace coverage** — every category, all 20 Italian regions, down to individual province and town.
- **Four ad types** — `vendita` (for sale), `regalo` (free), `cerco` (wanted), `affitto` (for rent).
- **Bulk keyword search** — run any number of queries in a single job; every row is traceable back to its query via `_input`.
- **Automatic pagination** — pages through results until your `maxItems` limit, deduplicating boosted ads that repeat across pages.
- **Resilient** — exponential-backoff retries on transient failures, and fail-fast with an actionable message on invalid input, so you're never billed for a silent retry loop.
- **Never crashes the run** — a failed page emits a structured `_error` row instead of killing the job.
- **Residential proxy support** — built-in Apify Proxy configuration.

### Input

```json
{
  "queries": ["iphone", "bicicletta"],
  "region": "annunci-lombardia",
  "province": "milano",
  "adType": "vendita",
  "category": "usato",
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

| Field | Type | Description |
|---|---|---|
| `queries` | array | One or more search terms. Each runs independently. Leave empty to browse a whole category. |
| `region` | string | `annunci-italia` (default, all of Italy) or an `annunci-<region>` slug like `annunci-lombardia`. A bare city name (`milano`) is **not** a valid region — use `province`. |
| `adType` | string | `vendita` (default), `regalo`, `cerco`, or `affitto`. |
| `category` | string | Category path segment. Default `usato`; also `auto`, `appartamenti`, `moto-e-scooter`, `offerte-lavoro`, and more. |
| `province` | string | Optional province slug, e.g. `milano`, `roma`. Must belong to the selected region. |
| `town` | string | Optional town slug to narrow further. Ignored unless `province` is set. |
| `categoryId` | string | Optional numeric category ID (e.g. `12` = Telefonia) to filter within the category path. |
| `shippableOnly` | boolean | Only return ads that offer shipping. |
| `subjectOnly` | boolean | Match the query against titles only, not body text. |
| `maxItems` | integer | Max ads per query. Default `100`. Use `0` for unlimited. |
| `proxyConfiguration` | object | Apify Proxy settings. Residential recommended for large runs. |

### Output

One row per ad. Real output from `queries: ["iphone"]`:

```json
{
  "adId": "657937931",
  "url": "https://www.subito.it/telefonia/iphone-14-128-gb-usato-ravenna-657937931.htm",
  "title": "IPhone 14 128 gb usato",
  "description": "Telefono in buone condizioni, display perfetto senza graffi, batteria ancora al 82 %, tutto funziona.",
  "price": 249,
  "currency": "EUR",
  "condition": "Buono - usato ma ben conservato",
  "adType": "vendita",
  "adTypeLabel": "In vendita",
  "category": "Telefonia",
  "categoryId": "12",
  "parentCategoryId": "9",
  "publishedAt": "2026-08-22T11:43:28+02:00",
  "location": "Ravenna, Ravenna, Emilia-Romagna",
  "region": "Emilia-Romagna",
  "province": "Ravenna",
  "provinceCode": "RA",
  "town": "Ravenna",
  "istatCode": "039014",
  "sellerId": "7484580",
  "sellerName": null,
  "sellerType": "private",
  "shopId": null,
  "shopName": null,
  "shippable": true,
  "shippingCost": 0.99,
  "shippingCarriers": ["poste_italiane", "ups", "inpost", "bartolini"],
  "shippingMethod": "Spedizione con TuttoSubito",
  "packageSize": "Piccolo - fino a 2kg",
  "imageCount": 6,
  "images": ["https://images.sbito.it/api/v1/sbt-ads-images-pro/images/35/357ec1cc-115f-4f89-9351-358b6becccf4?rule=gallery-desktop-2x-auto"],
  "thumbnails": ["https://images.sbito.it/api/v1/sbt-ads-images-pro/images/35/357ec1cc-115f-4f89-9351-358b6becccf4?rule=vertical-mini-card-1x-auto"],
  "attributes": { "phone_type": "Cellulari e Smartphone" },
  "_input": "iphone",
  "_page": 1,
  "_listingUrl": "https://www.subito.it/annunci-italia/vendita/usato/?q=iphone",
  "_source": "subito-search",
  "_scrapedAt": "2026-08-22T09:51:43.337496+00:00"
}
```

A full example is saved in [`sample_output.json`](sample_output.json). Every field is documented with types and examples in `.actor/dataset_schema.json`, so Apify Console, the API, and AI agents all know the shape up front.

#### Category-specific attributes

`attributes` adapts to whatever you scrape, with values already typed. A car listing:

```json
{
  "car": ["FIAT", "500X", "500X 1.6 MultiJet 120 CV Lounge"],
  "fuel": "Diesel",
  "gearbox": "Manuale",
  "mileage": "180.000 - 189.999",
  "mileage_scalar": 182000,
  "power": "88 kW / 120 Cv",
  "year": "2015",
  "register_date": "07/2015",
  "pollution": "Euro 6",
  "seats": "5",
  "color": "Grigio",
  "newdrivers_only": true
}
```

Real estate exposes `size`, `room`, `bathrooms`, `floor`, `energy_class`, `elevator`, `garden`; jobs expose `contract_type`, `work_hour`, `degree`. Numbers arrive as numbers, Sì/No as booleans, multi-value fields as arrays.

#### Error rows

A page that can't be fetched produces a structured row instead of failing the run:

```json
{
  "_error": "fetch_failed",
  "_errorDetail": "Subito returned its 'service unavailable' page for https://www.subito.it/milano/vendita/usato/ - check that region/adType/category/province/town slugs are valid (region must look like 'annunci-lombardia', not 'milano')",
  "_input": "divano",
  "_page": 1,
  "_source": "subito-search",
  "_scrapedAt": "2026-08-22T09:23:22.048637+00:00"
}
```

Filter on `_error` to separate failures from data.

### Notes

- **How it works** — Subito server-renders full structured ad data into the listing page, so the Actor reads it directly over plain HTTP. No headless browser, no reverse-engineered private API, no login.
- **Listing URLs are path-structured** — `/<region>/<adType>/<category>/[<province>/[<town>/]]`, which is why geography and category are separate input fields rather than query filters.
- **Invalid slugs fail fast** — Subito answers unroutable paths with an HTTP 200 "Servizio non disponibile" page rather than a 404. The Actor detects this and stops immediately with a message naming the likely cause.
- **Images are served as AVIF** — the CDN ignores the `Accept` header and always returns AVIF, regardless of the preset requested.
- **Cross-query duplicates are expected** — one ad matching two of your keywords appears once per query, distinguished by `_input`. Within a single query, results are deduplicated by `adId`.
- **Public data only** — the Actor reads publicly visible listings. It does not log in, and it does not collect phone numbers or other contact details hidden behind Subito's authentication.

# Actor input Schema

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

One or more keywords or phrases to search for. Each query runs independently and its results stream into the same dataset (joinable via the `_input` field). Leave empty to just browse the selected category/region with no keyword.

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

Subito.it URL region segment. Use `annunci-italia` for all of Italy, or an `annunci-<region>` slug such as `annunci-lombardia`, `annunci-lazio`, `annunci-veneto`. Note: a bare city name like `milano` is NOT a valid region — narrow to a city using the Province / Town fields below instead.

## `adType` (type: `string`):

`vendita` = for sale, `regalo` = free/giveaway, `cerco` = wanted ads, `affitto` = for rent.

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

Subito.it URL category segment, e.g. `usato` (general marketplace). Use `categoryId` below to filter to a specific category instead of changing this path.

## `province` (type: `string`):

Optional province slug to narrow results, e.g. `milano`, `roma`, `pescara`. Must belong to the region selected above (e.g. region `annunci-lombardia` + province `milano`).

## `town` (type: `string`):

Optional town slug to narrow further within the province, e.g. `milano`, `busto-garolfo`. Ignored unless Province is also set.

## `categoryId` (type: `string`):

Optional numeric Subito category ID (the `c` query parameter, e.g. `12` for Telefonia) to narrow results within the category path above.

## `shippableOnly` (type: `boolean`):

Only return ads that offer shipping.

## `subjectOnly` (type: `boolean`):

Match the query against ad titles only, not full body text.

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

Maximum number of ads to return per query. Set to `0` for unlimited (paginates through all available result pages).

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

Apify Proxy settings. Residential proxy is recommended for Subito.it to minimize rate limiting on larger runs.

## Actor input object example

```json
{
  "queries": [
    "iphone"
  ],
  "region": "annunci-italia",
  "adType": "vendita",
  "category": "usato",
  "shippableOnly": false,
  "subjectOnly": false,
  "maxItems": 30,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `ads` (type: `string`):

One row per Subito.it classified ad: title, numeric price, condition, seller, geographic location, directly usable image URLs, and a category-specific `attributes` map.

# 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 = {
    "queries": [
        "iphone",
        "bicicletta"
    ],
    "region": "annunci-italia",
    "adType": "vendita",
    "category": "usato",
    "maxItems": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("axery/subito-it-search-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 = {
    "queries": [
        "iphone",
        "bicicletta",
    ],
    "region": "annunci-italia",
    "adType": "vendita",
    "category": "usato",
    "maxItems": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("axery/subito-it-search-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 '{
  "queries": [
    "iphone",
    "bicicletta"
  ],
  "region": "annunci-italia",
  "adType": "vendita",
  "category": "usato",
  "maxItems": 30
}' |
apify call axery/subito-it-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,axery/subito-it-search-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/V29fSgrg4ygYJdfXt/builds/dIWds9GWRSRHwX4Ni/openapi.json
