# Immobiliare.it \[Only $0.50💰]| Search | Detail Pages | Agencies (`mostafa-ennadi/immobiliare-listings-agencies-scraper`) Actor

Scraper Immobiliare.it da $0.50/1.000 risultati: raccogli annunci e agenzie da URL di ricerca o dettaglio. Prezzi, superfici, foto, classe energetica, coordinate, telefoni ed email disponibili. Monitora nuovi annunci e variazioni di prezzo. Export JSON, CSV ed Excel.

- **URL**: https://apify.com/mostafa-ennadi/immobiliare-listings-agencies-scraper.md
- **Developed by:** [mostafa ennadi](https://apify.com/mostafa-ennadi) (community)
- **Categories:** Real estate, Lead generation
- **Stats:** 5 total users, 3 monthly users, 81.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 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.

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

## Immobiliare.it Listings & Agencies Scraper

**From $0.50 / 1,000 results 💰 · Search results · Property details · Agencies · Market monitoring**

Turn Immobiliare.it searches into property and agency datasets you can use for market research, investment screening and CRM workflows. Collect prices, surface area, rooms, descriptions, photos, floor plans, published phone numbers, location and energy information. Enable email enrichment to find published advertiser contacts, or use monitoring to follow new listings and price movements over time.

### Overview

The Actor collects public information from [Immobiliare.it](https://www.immobiliare.it/) using the URLs you provide. Start with a filtered property search, inspect individual listings, discover agencies in a city, or collect specific agency profiles. You can combine these URL types in one run and export the results as JSON, CSV or Excel.

Each property retains its available source fields and includes an `_enhanced` object with 87 convenient fields for analysis. Agencies have a separate record structure with their available contact details, location, opening hours and listing totals.

### What can you collect?

- **Property inventory:** search results and individual listings with price, contract, property type, size, rooms and available features.
- **Photos and location:** image and floor-plan links, coordinates, addresses, cities, macrozones and microzones where published.
- **Agency profiles:** names, phone numbers, websites, addresses, opening hours and available property statistics.
- **Contact enrichment:** published advertiser emails with a discovery status and source details.
- **Market changes:** new listings, price changes and listings that disappear from a monitored search.

### Features

- **Search and detail collection in one run.** Mix filtered searches, listing URLs, city agency directories and agency profiles.
- **Preserved search filters.** Use Immobiliare.it URLs to select geography, contract, property type, budget, surface, rooms and amenities.
- **Automatic pagination.** Continue through available search results up to your item and spending limits.
- **Flexible ordering.** Select recent listings, price, size, rooms, floor, price per square metre, discounts or advertiser type.
- **Incremental monitoring.** Deliver new IDs to the main Dataset and write detected changes to separate datasets.
- **Analysis-friendly fields.** Use raw records for detail and `_enhanced` fields for tables, filtering and comparisons.
- **Optional contact enrichment.** Add advertiser email results and payment-tool indicators when requested.
- **Predictable event pricing.** Pay $0.50 per 1,000 saved results, with separately priced enrichment and change events. See [Pricing](#pricing) for the start fee and examples.

### Supported URLs

| URL type | Example | Returns |
| --- | --- | --- |
| Property search | `https://www.immobiliare.it/vendita-case/roma/` | Property records from the filtered search. |
| Individual listing | `https://www.immobiliare.it/annunci/103009650/` | Details for that listing, when available. |
| City agency directory | `https://www.immobiliare.it/agenzie-immobiliari/pomezia/` | Agencies in the selected city. |
| Agency profile | `https://www.immobiliare.it/agenzie-immobiliari/385732/formula-pomezia-roma/` | Available details for that agency. |

Search URLs can include neighbourhood, price and surface filters. For example:

```text
https://www.immobiliare.it/vendita-case/roma/roma-70/?prezzoMassimo=300000&superficieMinima=60
```

Use the corresponding rental, auction or property-category URL when selecting a different market segment. City agency directories and individual profiles are supported; coverage of other directory formats can vary.

### Quick start

1. Open the Actor's **Input** tab and paste your Immobiliare.it URLs.
2. Choose a result limit and any sorting, contact or monitoring options.
3. Start the run and open its **Dataset** to inspect the collected records.
4. Export JSON, CSV or Excel, or retrieve the Dataset through the Apify API.

```json
{
  "startUrls": ["https://www.immobiliare.it/vendita-case/roma/"],
  "maxItems": 50,
  "sortBy": "mostRecent"
}
```

JSON callers may supply URL strings or objects containing a `url` field. Repeated URLs and repeated result IDs are deduplicated.

### Input configuration

| Field | Default | Behaviour |
| --- | --- | --- |
| `startUrls` | Required | One or more Immobiliare.it URLs. |
| `maxItems` | `10000` | Unique-record scan limit, from 1 to 10,000 across all supplied URLs. |
| `sortBy` | `auto` | Preserve URL ordering, or select date, price, size, rooms, floor, €/m², discount or advertiser type. |
| `outputLanguage` | `auto` | `it`, `en`, `fr`, `de`, `es`, `pt`, `ru`, `el`; translations depend on availability. |
| `maxConcurrency` | `10` | Collection concurrency, from 1 to 50. |
| `minConcurrency` | `1` | Compatibility setting; cannot exceed maximum concurrency. |
| `maxRequestRetries` | `5` | Retry budget, from 0 to 100. |
| `includeAgencyDetails` | `true` | Include full profiles when collecting agency directories. |
| `monitoringMode` | `false` | Save only records not delivered in previous runs of the same search and sort settings. |
| `detectPriceChanges` | `false` | With monitoring, save price changes in a separate dataset. |
| `detectRemovedListings` | `false` | With monitoring and a confirmed full search scan, report records no longer present. |
| `enrichEmails` | `false` | Best-effort email discovery from published advertiser website homepages, for properties and agencies. |
| `qualifyByPayment` | `false` | With email enrichment, identify payment tools on those websites. |
| `proxy` | Empty | Accepted for compatibility; managed connectivity is used. |
| `maxUnblockerRequests` | `60` | Accepted for compatibility; no paid unblocking requests are purchased. |

Standard date, price, size and room sorting is applied before collecting results. Floor, discount, €/m² and advertiser filtering compare up to 10,000 records per search before selecting the requested results. These comparisons can take longer; removal detection is conservatively skipped for comparison-sorted runs.

#### Choose the result order

`sortBy: "auto"` preserves the order in your URL. Available alternatives are:

| Goal | `sortBy` values |
| --- | --- |
| Site ranking | `relevance` |
| Listing date | `mostRecent`, `oldest` |
| Price | `priceLowToHigh`, `priceHighToLow` |
| Surface area | `biggest`, `smallest` |
| Room count | `mostRooms`, `fewestRooms` |
| Price per square metre | `pricePerSqmLowToHigh`, `pricePerSqmHighToLow` |
| Floor | `highestFloor`, `lowestFloor` |
| Price reduction | `discounted` |
| Advertiser | `privateSellers`, `agenciesOnly` |

For a recurring check of recent listings, use `mostRecent` with an appropriate `maxItems`. An explicit order takes precedence over the advertiser filter in a `da-privati` or `da-agenzie` URL; select the advertiser option in `sortBy` when that is your priority.

### Property output

Each Dataset item represents one unique property or agency. Raw published fields are preserved where available; fields that cannot be obtained are not invented.

This shortened example illustrates a property record. Values are fictional; actual fields and availability depend on the listing.

```json
{
  "id": 123456789,
  "dataType": "property",
  "title": "Appartamento con terrazzo",
  "price": {
    "raw": 245000,
    "value": "€ 245.000",
    "currency": "EUR",
    "isHidden": false
  },
  "topology": {
    "surface": {"size": 95, "unitOfMeasure": "m²"},
    "rooms": "3",
    "bathrooms": "2",
    "floor": "2",
    "lift": true,
    "terrace": true
  },
  "geography": {
    "municipality": {"name": "Roma"},
    "province": {"id": "RM", "name": "Roma"},
    "street": "Via Esempio 10",
    "geolocation": {"latitude": 41.9, "longitude": 12.5}
  },
  "contacts": {
    "agencyId": 12345,
    "phones": [{"type": "tel1", "num": "+390000000000"}]
  },
  "author": {"id": 12345, "type": "agency", "displayName": "Agenzia Esempio"},
  "description": {"reference": "EXAMPLE-01", "content": "<p>Example property description.</p>"},
  "_enhanced": {
    "listingUrl": "https://www.immobiliare.it/annunci/123456789/",
    "priceAmount": 245000,
    "priceCurrency": "EUR",
    "pricePerSqm": 2578.95,
    "surfaceSqm": 95,
    "rooms": 3,
    "bathrooms": 2,
    "floor": "2",
    "hasLift": true,
    "hasTerrace": true,
    "city": "Roma",
    "latitude": 41.9,
    "longitude": 12.5,
    "agencyName": "Agenzia Esempio",
    "contactPhones": ["+390000000000"]
  }
}
```

Property records include `id`, `uuid`, `title`, `price`, `contract`, `topology`, `geography`, `analytics`, `media`, `contacts`, `author`, `description`, `energyClass`, `mainData`, `surfaceConstitution`, `infoCosts`, `costs`, `mortgage` and `basicInfo`, when available. Phone numbers appear in `contacts.phones[].num`.

#### Convenient fields in `_enhanced`

The `_enhanced` object adds convenient fields including:

- Price: `priceAmount`, `priceCurrency`, `priceFormatted`, `pricePerSqm`.
- Property: `surfaceSqm`, `rooms`, `bedrooms`, `bathrooms`, `floor`, `propertyType`, `contractType` and feature flags.
- Location: `address`, `city`, `province`, `region`, `latitude`, `longitude`, `macrozone`, `microzone`.
- Media: `photoUrls`, `photoUrlsHd`, `photos`, `floorplanUrls`, `floorplanUrlsHd`, `floorplanIds`.
- Contacts: `agencyName`, `agencyId`, `agencyAddress`, `contactPhones` and `listingUrl`.
- Dates, status, energy, costs and mortgage convenience fields.

Unavailable convenience fields use `null`, `[]` or `false`, according to their type. Phone numbers, email addresses, coordinates and all other fields depend on what the advertiser publishes. Translations do not guarantee that every free-text field is translated.

### Agency output

Agency records use `dataType: "agency"` and expose `name`, `address`, `phones`, `location`, `realEstateAds`, `realEstateSales`, `openingHours`, `url`, `website` and `basicInfo` when available, alongside the original agency fields. Staff and website-only promotional fields may be unavailable. Set `includeAgencyDetails: false` for lighter directory records.

Illustrative shortened agency record:

```json
{
  "id": 12345,
  "dataType": "agency",
  "name": "Agenzia Esempio",
  "address": "Via Esempio 10, Roma",
  "url": "https://www.immobiliare.it/agenzie-immobiliari/12345/",
  "website": "https://agenzia.example/",
  "phones": [
    {"type": "tel1", "value": "+390000000000", "formattedValues": "+390000000000", "isVirtual": false}
  ],
  "location": {
    "city": {"name": "Roma"},
    "latitude": 41.9,
    "longitude": 12.5
  },
  "realEstateAds": 42,
  "realEstateSales": 12,
  "openingHours": [{"day": 1, "hours": [["09:00", "18:00"]]}],
  "agents": []
}
```

### Email enrichment and payment qualification

Set `enrichEmails: true` to add `contactEmail`, `contactWebsite` and `emailEnrichment` to properties and agencies. `contactEmail` is the preferred published email, or `null`; `contactWebsite` is the advertiser's website homepage, or `null`. The `emailEnrichment` object includes `status`, `reason`, `source`, `emails`, `requestedUrl`, `finalUrl`, `httpStatus` and, when a website was requested, `durationMs`. Status is `found`, `not_found`, `not_applicable` or `unavailable`. An inaccessible website does not fail the collection. When enrichment is disabled, no email fields are added.

Illustrative contact fields when an email is found:

```json
{
  "contactEmail": "info@agenzia.example",
  "contactWebsite": "https://agenzia.example/",
  "emailEnrichment": {
    "status": "found",
    "reason": "email_found_on_homepage",
    "source": "homepage",
    "emails": ["info@agenzia.example"],
    "requestedUrl": "https://agenzia.example/",
    "finalUrl": "https://agenzia.example/",
    "httpStatus": 200,
    "durationMs": 120
  }
}
```

To enable enrichment:

```json
{
  "startUrls": ["https://www.immobiliare.it/vendita-case/roma/"],
  "maxItems": 5,
  "enrichEmails": true
}
```

Set `qualifyByPayment: true` together with `enrichEmails: true` to add `takesPayments`, `paymentProcessors`, `stripeLiveKey` (only a public publishable key) and `paymentConfidence`. These fields describe payment-tool indicators found on the website; they do not verify that an advertiser accepts a particular transaction. Qualification preserves email results and reports no payment match when a website is unavailable.

Export the Dataset as JSON, CSV or Excel from Apify.

### Monitor new listings and market changes

Enable `monitoringMode` to build a recurring feed, then choose whether to detect price changes and removals:

```json
{
  "startUrls": ["https://www.immobiliare.it/vendita-case/roma/"],
  "maxItems": 10000,
  "monitoringMode": true,
  "detectPriceChanges": true,
  "detectRemovedListings": true
}
```

The first run establishes the baseline. Later runs save only new IDs in the default Dataset. Previously seen IDs still count toward `maxItems`, so a small cap checks only that portion of the search.

| Option | Delivered data | Billing |
| --- | --- | --- |
| `monitoringMode` | New property or agency IDs in the main Dataset. | Result price for newly saved records. |
| `detectPriceChanges` | One event for each detected price movement. | $0.0007 per saved change event. |
| `detectRemovedListings` | One event for each listing absent from a confirmed complete search. | $0.0007 per saved removal event. |

Price changes go to `immobiliare-changes-<runId>` with `propertyId`, `url`, `oldPrice`, `newPrice`, `priceDelta`, `pctChange`, `direction` and `firstSeenAt`. Removed listings go to `immobiliare-removed-<runId>` with `propertyId`, `url`, `searchUrl` and `detectedRemovedAt`. These datasets are created only when an event is found. Their IDs are included in the `OUTPUT` run summary.

Removal means that a listing disappeared from the monitored search; it does not confirm a sale. Removal checks are skipped when the result cap is reached, a collection error occurs, details are incomplete, or a full search cannot be confirmed. Monitoring history is updated only after the result writes succeed. Keep the same URLs and sort settings between runs.

### Run summary

The `OUTPUT` record includes item, error, skipped-listing, price-change and removed-listing counts plus result Dataset IDs. Partial source failures are counted and clearly reported. A total collection failure marks the run as failed.

### Pricing

| Event | Price | Charged for |
| --- | --- | --- |
| Result | **$0.50 / 1,000** | Each unique property or agency saved in the default Dataset. |
| Additional Data | **$0.70 / 1,000** | Each saved record with a found contact email, or each saved price-change or removed-listing event. |
| Actor Start | **$0.005** | Starting a run; one event at the Actor's 128 MB memory allocation. |

The same event prices apply to every subscription tier. Standard run platform usage is included in the event prices. Email misses, duplicate records and previously seen records skipped during monitoring incur no result or email charge. A record with several discovered emails incurs one Additional Data event. Payment qualification has no separate fee.

For example, 1,000 saved results without email enrichment cost $0.505 including one start. With 100 of those results containing a found contact email, the total is $0.575. Your maximum charge per run can limit the number of results; the run summary reports when the spending limit constrained collection.

The Actor uses 128 MB and processes records in bounded batches. No browser or user-provided credentials are required. Consult the Actor's Pricing tab for the active event prices. Storage access after a run can incur standard Apify charges.

### Typical workflows

- **Market research:** compare asking prices, property size and available features across city districts.
- **Investment screening:** collect a budget-filtered search and rank the results in your own analysis.
- **Agency mapping:** combine city directories with profile details to build a brokerage database.
- **CRM enrichment:** collect published agency phone numbers and optionally discover website emails.
- **Inventory monitoring:** schedule repeated searches to follow new listings, price movements and disappearing inventory.

### FAQ

#### Does the Actor return phone numbers?

Yes, when the advertiser publishes them. Properties expose phone records in `contacts.phones` and convenient numbers in `_enhanced.contactPhones`. Agencies expose `phones`. Some published numbers are virtual contact numbers; agency phone records include `isVirtual` where it can be identified.

#### Are emails included in every result?

Email enrichment is optional and depends on the advertiser having a website with a published email. Enable `enrichEmails` and inspect `emailEnrichment.status`. A miss does not incur an Additional Data charge.

#### Can one run collect properties and agencies?

Yes. Add search, listing, city-directory and agency-profile URLs to `startUrls`. Each output record includes `dataType` so you can separate properties and agencies after export. `maxItems` applies across the supplied URLs.

#### Why are some fields empty or absent?

Listings and agency profiles publish different levels of detail. Missing convenience values use `null`, `[]` or `false`; unavailable source fields can be absent. Hidden prices, unpublished phones and agency staff data are not reconstructed. Localized fields also depend on the translations available for the source record.

#### Why did a run return fewer records than requested?

A search can contain fewer available results, duplicate IDs can be skipped, and monitoring returns only new IDs. The maximum charge per run can also reduce the output. Check the `OUTPUT` summary for counts, partial errors and spending-limit warnings.

### Disclaimer

This is an independent tool and is not affiliated with Immobiliare.it. It collects public information; availability and field coverage vary with the source.

The input form starts with **5 results** for a quick preview. Increase **Maximum results** up to **10,000** for larger searches. API calls that omit `maxItems` use **10,000**.

# Actor input Schema

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

Paste public Immobiliare.it search, listing or agency URLs. JSON callers may also pass objects with a url field. URL filters are preserved.

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

The form starts with 5 results for a quick preview. Increase up to 10,000 as needed. API calls that omit this field use 10,000. This is the unique-record scan limit across supplied URLs, including seen records in monitoring mode.

## `monitoringMode` (type: `boolean`):

Save only records not delivered in earlier runs using the same search URLs and sort settings.

## `detectPriceChanges` (type: `boolean`):

Requires monitoring mode. Save price-change events to a separate immobiliare-changes-<runId> dataset.

## `detectRemovedListings` (type: `boolean`):

Requires monitoring mode and a confirmed complete search scan. Save removed events to a separate dataset. Truncated, failed or comparison-sorted searches skip removal checks.

## `maxConcurrency` (type: `integer`):

Maximum simultaneous collection requests. Range: 1–50.

## `minConcurrency` (type: `integer`):

Accepted for compatibility; must not exceed maxConcurrency.

## `maxRequestRetries` (type: `integer`):

Retry budget for collection requests. Permanent errors are not retried. Range: 0–100.

## `includeAgencyDetails` (type: `boolean`):

Include full profiles for agencies discovered in a directory. Disable for lighter summary records.

## `enrichEmails` (type: `boolean`):

Find published emails on advertiser website homepages for properties and agencies. Adds contactEmail, contactWebsite and emailEnrichment with all discovered emails and found/not_found/not_applicable/unavailable status. Unavailable sites do not fail collection.

## `qualifyByPayment` (type: `boolean`):

Requires enrichEmails. Identify payment tools on advertiser websites, including public Stripe publishable keys where present. Email enrichment results are preserved.

## `outputLanguage` (type: `string`):

Language for localized fields where translations are available. Auto uses Italian, or English for English-language source URLs.

## `sortBy` (type: `string`):

Auto preserves URL order. Date, price, size and rooms sort before collection. Floor, discount, price/m² and advertiser filters compare up to 10,000 records per search and can take longer.

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

Accepted for compatibility. Managed connectivity is used; this setting does not override it.

## `maxUnblockerRequests` (type: `integer`):

Accepted for compatibility. No paid unblocking requests are purchased by this Actor.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.immobiliare.it/vendita-case/roma/"
  ],
  "maxItems": 5,
  "monitoringMode": false,
  "detectPriceChanges": false,
  "detectRemovedListings": false,
  "maxConcurrency": 10,
  "minConcurrency": 1,
  "maxRequestRetries": 5,
  "includeAgencyDetails": true,
  "enrichEmails": false,
  "qualifyByPayment": false,
  "outputLanguage": "auto",
  "sortBy": "auto",
  "maxUnblockerRequests": 60
}
```

# Actor output Schema

## `results` (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 = {
    "startUrls": [
        "https://www.immobiliare.it/vendita-case/roma/"
    ],
    "maxItems": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("mostafa-ennadi/immobiliare-listings-agencies-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 = {
    "startUrls": ["https://www.immobiliare.it/vendita-case/roma/"],
    "maxItems": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("mostafa-ennadi/immobiliare-listings-agencies-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 '{
  "startUrls": [
    "https://www.immobiliare.it/vendita-case/roma/"
  ],
  "maxItems": 5
}' |
apify call mostafa-ennadi/immobiliare-listings-agencies-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mostafa-ennadi/immobiliare-listings-agencies-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/fRy8KM04niBbRDXa3/builds/c2hbJUwufVqrxiE0B/openapi.json
