# Sutochno.ru Scraper - Rentals, Prices, Availability & Reviews (`abotapi/sutochno-ru-scraper`) Actor

Scrape Sutochno.ru short-term rentals, apartments and hotels by city, dates, guests or URL. Extract property details, stay prices, availability, ratings, guest reviews, amenities and owner information. Supports listing, hotel and search URLs for rental research and price comparison.

- **URL**: https://apify.com/abotapi/sutochno-ru-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Security:** Limited permissions
- **Stats:** 1 total users, 1 monthly users, 76.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 listing records

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

## Sutochno.ru Scraper

Scrape Sutochno.ru, Russia's largest short-term-rental platform and the domestic alternative to Airbnb: apartment and house listings with real stay prices, availability, ratings, guest reviews, amenities and owner profiles. Search any city with your dates and guest count, or paste listing, hotel and search links.

### Why This Scraper?

- **Real stay pricing, not brochure rates.** Every listing is priced for your exact check-in and check-out dates: per-night rate, stay total, season price rows, long-stay tiers, prepayment and service fee.
- **Reviews behind pagination.** Guest reviews are collected past the first page (up to your per-listing limit) with ratings, stay dates, party size and text, into a dedicated Reviews tab.
- **Detail records, not just cards.** House rules, check-in and check-out windows, the full amenity set, owner response stats and the complete photo gallery come off each listing's detail record.
- **Availability signals per stay window.** Booking availability, rooms left and max guests are read for your dates, so occupancy analytics work out of the box.
- **Filters as first-class inputs.** Housing types, hotel stars, guest score, instant booking and the site's own sort orders reach the site server-side, not as post-hoc guesses.
- **Built for schedules.** Incremental mode tracks listings between runs and returns only new or changed ones; resume continues an interrupted run; both are first-class inputs.

### Use Cases

- **Who:** Price analysts and revenue managers tracking daily rates across Russian cities for specific stay windows.
- **Who:** Investors and hosts benchmarking occupancy signals (availability, rooms left) and competitor amenities in their market.
- **Who:** Travel and relocation researchers comparing neighborhoods by price, rating, reviews and transit notes.
- **Who:** Data teams feeding RU rental inventory into dashboards or alerts through the dataset, API or MCP connectors.

### Data You Get

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

#### Fields (highlights)

| Field | Example |
| --- | --- |
| `objectId`, `recordId`, `url` | `12345678`, `sutochno:12345678`, listing link |
| `title`, `typeTitle`, `hotelTitle`, `hotelStars` | `Студия`, `квартиры, апартаменты`, hotel block for hotels |
| `pricePerNight`, `fullPrice`, `periodNights`, `currency` | `5000`, `10000`, `2`, `RUB` |
| `prepayment`, `serviceFee`, `bonus` | stay cost breakdown |
| `seasonPrices`, `extPrices` | per-period and long-stay price tiers |
| `busyStatus`, `roomsAvailable`, `maxGuests` | `unbusy`, `1`, `3` |
| `rating`, `countReviews`, `reviewsTotal` | `4.9`, `27`, `27` |
| `reviews[]` | rating, text, author, dates, stay size, images |
| `address`, `cityTitle`, `lat`, `lng`, `metroStations` | location block |
| `area`, `bedrooms`, `beds`, `guests`, `roomsCount`, `floor` | capacity block |
| `checkInAfter`, `checkOutUntil`, `minNights`, `earlyCheckIn` | house rules |
| `wifi`, `parking`, `airConditioning`, `washmachine`, `tv` | amenity flags |
| `ownerName`, `ownerAnswerRate`, `ownerAnswerTimeMinutes`, `ownerSince` | owner profile |
| `mediaUrls`, `photoCount` | full photo gallery |
| `changeType`, `changedFields`, `firstSeenAt`, `lastSeenAt` | incremental bookkeeping |

Output tabs: **Listings** (overview), **Full listing details**, **Reviews** (one row per review), **Changes** (incremental mode).

### How to Use

**Search a city with dates and guests:**

```json
{
    "mode": "search",
    "location": "Санкт-Петербург",
    "checkIn": "2026-12-04",
    "checkOut": "2026-12-07",
    "guestsAdults": 2,
    "maxItems": 50
}
```

**Search with filters and sorting:**

```json
{
    "mode": "search",
    "location": "Сочи",
    "sortings": "price_asc",
    "housingTypes": ["apartment", "hotel"],
    "minReviewScores": ["8", "9"],
    "maxItems": 100
}
```

**Read pasted links:**

```json
{
    "mode": "urls",
    "urls": ["https://sochi.sutochno.ru/998663"],
    "fetchDetails": true,
    "fetchReviews": true
}
```

**Supported link shapes (URLs mode):**

| Link | What it reads |
|---|---|
| `sochi.sutochno.ru/998663`, `sutochno.ru/998663`, `m.sutochno.ru/998663`, `sutochno.ru/front/searchapp/detail/858763` | one listing |
| `sutochno.ru/hotels/144264` (optional `?occupied=2026-12-10;2026-12-13`) | one hotel listing; the dates set its stay and price window; a window that starts before today is ignored with a warning and the relative default window is used |
| `sutochno.ru/front/searchapp/search?term=...` | a search; `occupied`, `guests_adults`, `sortings` (0 relevance, 1 price up, 2 price down), `is_hotel`/`is_house`/... flags, `id`+`type` and `page` are honoured |
| `spb.sutochno.ru/`, `spb.sutochno.ru/?page=2` | everything listed for that city |
| `spb.sutochno.ru/hotels` (also house and hostel categories) | that city, narrowed to the category |
| `spb.sutochno.ru/1-komnatnye` | the whole city: room-count categories have no server-side filter, so a warning is logged and the scope counts as partial |
| `sutochno.ru/armenia` | everything listed for that country |

A link with `?page=N` (N above 1) starts at that page and counts as a partial scope, so incremental runs never mark unseen listings as expired. If you leave the URL list untouched, URLs mode scrapes one example of each shape above. Search mode ignores the list.

#### Run it from your code

Python (Apify client 3.x):

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("abotapi/sutochno-ru-scraper").call(run_input={
    "mode": "search",
    "location": "Санкт-Петербург",
    "checkIn": "2026-12-04",
    "checkOut": "2026-12-07",
    "maxItems": 50,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["title"], item["pricePerNight"], item["fullPrice"])
```

JavaScript:

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('abotapi/sutochno-ru-scraper').call({
    mode: 'search',
    location: 'Санкт-Петербург',
    checkIn: '2026-12-04',
    checkOut: '2026-12-07',
    maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((i) => [i.title, i.pricePerNight, i.fullPrice]));
```

#### Tips

- **Set both dates to see real prices.** Prices on the site depend on the stay window; without dates the actor prices a default 30-night window for availability.
- **Min/Max price are applied after collection** (the site filters price in the browser the same way), so Max items counts listings before the price filter narrows them.
- **Unknown location?** Use the city name as the site spells it; the actor resolves your text against the site's own location directory and fails with a clear message when it is not there.
- **Incremental schedules:** keep the same location, dates and filters so the scope hash stays stable; new and changed listings are billed, unchanged ones are not.

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

Optionally send results into the apps you already use through Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape; the dataset is never changed and the full record always stays in it.

1. Authorize a connector once under Apify -> Settings -> Integrations.
2. Select it in the `mcpConnectors` field.
3. For Notion, also set `notionParentPageUrl`. `maxNotifyListings` caps how many listings each connector receives per run.

Leave the field empty to skip.

### Input Parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `mode` | select | `search` | `search` walks a location; `urls` reads pasted links. |
| `location` | string | `Санкт-Петербург` | Search mode: city, region or address the site knows. |
| `checkIn` | date | none | Check-in date (YYYY-MM-DD). |
| `checkOut` | date | none | Check-out date; defaults to one night after check-in. |
| `guestsAdults` | integer | `2` | Adult guests the search should fit. |
| `guestsChildrens` | array | `[]` | Child guest ages (0-17), e.g. `[4, 9]`. |
| `pets` | boolean | `false` | Only listings that accept pets. |
| `sortings` | select | `relevance` | `relevance`, `price_asc` or `price_desc` as the site serves it. |
| `maxItems` | integer | `20` | Maximum listings per run; 0 walks to the natural end. |
| `maxPages` | integer | `0` | Page cap per scope; 0 walks until results run out. |
| `housingTypes` | multi-select | `[]` | apartment, hotel, house, room, bed, mini_hotel, aparthotel (applied by the site). |
| `stars` | multi-select | `[]` | Hotel star ratings; `none` = unrated hotels. |
| `minReviewScores` | multi-select | `[]` | Guest score filter values 6-9 (the site's own filter). |
| `bookingNow` | boolean | `false` | Only instantly bookable listings. |
| `priceMin` | integer | none | Minimum price per night, RUB, applied after collection. |
| `priceMax` | integer | none | Maximum price per night, RUB, applied after collection. |
| `urls` | URL list | one example of each shape | URLs mode: listing, hotel, search-app, city and country page links. Leave it untouched and URLs mode scrapes one example of each supported shape (see the Supported link shapes table above); it never rides a search-mode run. |
| `fetchDetails` | boolean | `true` | Read each listing's detail record (description, amenities, rules, owner, full gallery). |
| `fetchReviews` | boolean | `true` | Collect guest reviews into a nested field. |
| `maxReviews` | integer | `20` | Review cap per listing (0 to 1000); 0 skips reviews. |
| `fetchAvailability` | boolean | `true` | Price the stay window: total, season rows, prepayment, availability. |
| `availabilityDays` | integer | `30` | Stay window length when no dates are set (1-90 nights). |
| `proxyConfiguration` | proxy | Apify proxy | The site is open; the default connection works. Residential supported if selected. |
| `resumeFromRunId` | string | none | Continue a previous unfinished run. |
| `incrementalMode` | boolean | `false` | Scheduled runs return only NEW or CHANGED listings. |
| `stateKey` | string | auto | Named incremental baseline (advanced). |
| `emitUnchanged` | boolean | `false` | Also return UNCHANGED listings in incremental mode. |
| `changeScope` | string | `all` | Incremental mode: `all` compares the whole record; `priceAndStock` compares only price and availability fields (pricePerNight, priceFull, priceWithoutDiscounts, fullPrice, busyStatus, roomsAvailable, bookingNow, extPrices, seasonPrices). Photo host rotation and review order never count as a change. Fields are compared after the run has read the listing's detail, availability and reviews (as far as those are switched on), so a changed availability or price shows up as UPDATED; re-reading an unchanged listing is not billed, only delivered rows are. Without fixed dates the moving window totals and season price segments (which shift with the run date) are ignored, so a plain re-run does not re-flag every listing as CHANGED. |
| `emitExpired` | boolean | `false` | Label listings that disappeared from the scope as EXPIRED. EXPIRED means the listing no longer appears in the results, not that it is unavailable for your dates (see busyStatus and roomsAvailable). |
| `compactUpdates` | boolean | `false` | Return UPDATED and EXPIRED listings as slim rows: identifiers, current price and availability, plus `priceChanges` and `variantChanges` with old and new values. NEW listings stay full. A slim UPDATED row bills the availability read only, never a detail record or reviews it does not carry. |
| `expireAfterMissedScans` | integer | `1` | With Emit expired: label a listing EXPIRED only after it was missing from this many complete scans in a row. |
| `ignoreFieldsForChanges` | array | `[]` | Dataset fields excluded from change detection. A dotted path such as `seasonPrices.type` drops that key from every element of the list. |
| `mcpConnectors` | array | `[]` | Send results into your apps (MCP connectors). |
| `notionParentPageUrl` | string | none | Notion connector only: page under which listing pages are created. |
| `maxNotifyListings` | integer | `50` | Cap on listings exported to each connector per run (1 to 1000). Does not affect the dataset. |

### Output Example

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

**One listing from a city search (2-night stay window):**

```json
{
    "recordId": "sutochno:12345678",
    "kind": "listing",
    "objectId": 12345678,
    "title": "Студия",
    "typeTitle": "квартиры, апартаменты",
    "url": "https://sutochno.ru/front/searchapp/detail/12345678",
    "pricePerNight": 5000,
    "fullPrice": 10000,
    "periodNights": 2,
    "currency": "RUB",
    "busyStatus": "unbusy",
    "rating": 4.9,
    "countReviews": 27,
    "bookingNow": true,
    "photoCount": 21,
    "address": "ул. Примерная, 10",
    "cityTitle": "Санкт-Петербург",
    "area": 26,
    "bedrooms": 1,
    "guests": 2,
    "wifi": true,
    "checkInAfter": "15:00",
    "checkOutUntil": "12:00",
    "ownerName": "Анна",
    "ownerAnswerRate": 100,
    "reviews": [
        {
            "reviewId": 123456789,
            "rating": 5,
            "reviewText": "Все ок, цена качество, соответствует.",
            "reviewAuthor": "Guest",
            "reviewDate": "2026-10-01 10:00:00",
            "stayNights": 3
        }
    ],
    "changeType": "NEW"
}
```

### Plan Requirement

This actor uses Pay Per Event pricing. Four events exist, each charged exactly as follows:

| Event | Unit | When it fires |
|---|---|---|
| `apify-actor-start` | one per run | once, when the run starts |
| `apify-default-dataset-item` | one per row | each row actually saved to the dataset |
| `detail-enrichment` | one per served read | one for a served detail record and one for a served availability/stay-price read, billed with the row they enrich |
| `review-enrichment` | one per listing | one per saved listing whose reviews were collected (not one per individual review) |

Enrichment events are charged only for rows that were saved, so card-only, suppressed and unchanged rows cost proportionally less. Check the Pricing tab on the actor page for the current per-event prices and your plan's tier rates.

### FAQ

#### How much does a run cost?

The start event fires once per run. Each listing returned bills the dataset-item event; each served detail record and availability read bills one detail-enrichment unit each; a listing with collected reviews bills one review event. Card-only runs (enrichment off) bill the dataset-item event only.

#### Is it legal to scrape Sutochno.ru?

The actor reads the same public listing pages and JSON interface the site's own web app requests, without logging in and without bypassing any protection. Collect publicly available data responsibly: respect the site's terms, do not request data about private individuals beyond what listings publish, and keep run volumes reasonable.

#### How do I schedule recurring runs?

Enable Incremental mode and run the actor on a schedule (daily works well). The actor keeps a baseline in its named key-value store keyed by your search scope, returns only NEW or CHANGED listings, and can label disappeared ones as EXPIRED with Emit expired (optionally only after several missed complete scans). Turn on Compact updates for slim price and availability change rows.

#### Why did my run return fewer results than the site shows?

The site caps its map-lane result counter at 10,000; a walk ends at the natural end of pages. Max items, Max pages and the run time limit also stop a walk early (the status message says so). Min/max price filters apply after collection, so counts before and after the price filter can differ.

#### Can I use this actor with AI agents or MCP?

Yes. Add an MCP connector to the mcpConnectors input to push results into your connector-enabled app, or read the dataset through Apify's MCP server. The actor's structured fields (prices, availability, reviews, rules) are designed for downstream LLM consumption.

#### Does the actor log in or need an account?

No. Everything shipped here is public: listings, prices, availability and guest reviews.

### 🔗 Want more travel data?

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

<table>
<tr><td>🏨 <a href="https://apify.com/abotapi/airbnb-stays-reviews-scraper"><b>Airbnb Scraper</b></a><br>Scrape Airbnb stays by destination or link: nightly and total price, rating breakdown...</td><td>🏨 <a href="https://apify.com/abotapi/trip-com-scraper"><b>Trip.com Hotels, Rooms &amp; Reviews Scraper</b></a><br>Pull structured hotel listings from trip.com with prices, room types, amenities...</td></tr>
<tr><td>🏨 <a href="https://apify.com/abotapi/wego-com-scraper"><b>Wego Scraper</b></a><br>Scrape Wego hotels by city or search URL. Get rates, providers, booking links...</td><td>🏨 <a href="https://apify.com/abotapi/booking-com-scraper"><b>Booking.com Scraper</b></a><br>Scrape booking.com hotels, apartments, villas and hostels. Search any destination with...</td></tr>
<tr><td>🏨 <a href="https://apify.com/abotapi/expedia-universal-scraper"><b>Expedia Hotels Scraper</b></a><br>Scrape Expedia.com hotel listings and reviews for any destination. Extract prices...</td><td>🏨 <a href="https://apify.com/abotapi/rakuten-travel-scraper"><b>Rakuten Travel Scraper</b></a><br>Scrape Rakuten Travel, Japan's largest domestic hotel-booking site, by prefecture...</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/sutochno-ru-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

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

search: walk listing pages for a location with your dates and guests. urls: read the sutochno.ru links you paste (listing pages, hotel pages, search links).

## `location` (type: `string`):

Search mode: a city, region or address the site knows (Russian or Latin both work, e.g. 'Санкт-Петербург', 'Sochi'). The search is scoped to this location.

## `checkIn` (type: `string`):

Check-in date (YYYY-MM-DD). Prices on the site depend on the stay window, so set both dates to see real prices. Leave both empty to browse without a stay window.

## `checkOut` (type: `string`):

Check-out date (YYYY-MM-DD), must be after check-in. If check-in is set and this is empty, one night is assumed.

## `guestsAdults` (type: `integer`):

Number of adult guests the search should fit.

## `guestsChildrens` (type: `array`):

Ages of child guests (0-17), e.g. \[4, 9]. The site uses ages, not just a count.

## `pets` (type: `boolean`):

Only listings that accept pets.

## `sortings` (type: `string`):

Listing order as the site serves it: relevance (the site's own order), price ascending or price descending.

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

Maximum listings collected per run (0 to 100000). 0 means no limit (the walk stops at the natural end of results).

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

Maximum result pages walked per scope. 0 (default) walks until results run out; Max items is the only limit that stops a run early.

## `housingTypes` (type: `array`):

Restrict to selected housing types (applied by the site itself). Empty = all types.

## `stars` (type: `array`):

Restrict to selected hotel star ratings ('none' = unrated hotels). Empty = all.

## `minReviewScores` (type: `array`):

Only listings whose guest score is one of the selected values (the site's own 6-9 score filter). Empty = any.

## `bookingNow` (type: `boolean`):

Only listings bookable instantly without owner approval.

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

Minimum price per night, RUB. Applied after collection (the site filters price in the browser too), so Max items counts listings before this filter narrows them.

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

Maximum price per night, RUB. Applied after collection (see Min price per night).

## `urls` (type: `array`):

URLs mode: listing pages (sutochno.ru/front/searchapp/detail/<id>, <city>.sutochno.ru/<id>, sutochno.ru/<id>), hotel pages (sutochno.ru/hotels/<id>, optional ?occupied=from;to), search-app links (term, occupied, guests_adults, sortings, page, is_hotel, id, type), and city or country pages (spb.sutochno.ru/, /hotels, /?page=2, sutochno.ru/armenia). If you add no links, one example of every supported shape is used. In search mode this list is ignored.

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

Read each listing's detail record: full description, all amenities, house rules, check-in/out rules, owner profile, long-stay price tiers, and the full photo set.

## `fetchReviews` (type: `boolean`):

Collect guest reviews for each listing (up to Max reviews per listing) into a nested reviews field. The Reviews output tab lists them one per row.

## `maxReviews` (type: `integer`):

Maximum guest reviews collected per listing (0 to 1000). 0 skips reviews.

## `fetchAvailability` (type: `boolean`):

Price each listing for a stay window: total stay price, per-period season prices, prepayment, service fee, booking availability and rooms left.

## `availabilityDays` (type: `integer`):

Length of the stay window priced per listing (used when Check-in/Check-out are empty): 1-90 nights, default 30.

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

The site is open and the default datacenter connection works. Residential proxies are supported if you select them.

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

Continue a previous unfinished run: listings already collected by that run are skipped. Leave empty for a fresh run.

## `changeScope` (type: `string`):

Incremental mode: which fields decide UPDATED. 'All fields' compares every field the run reads for the listing (card, detail, availability and reviews, as far as those are switched on). 'Prices and availability only' compares pricePerNight, priceFull, priceWithoutDiscounts, fullPrice, busyStatus, roomsAvailable, bookingNow, extPrices and seasonPrices, so description, photo or owner edits never produce an UPDATED row. Without fixed Check-in/Check-out dates the availability window moves with the run date, so the window totals (fullPrice, periodNights, prepayment, serviceFee, bonus, seasonPrices) are left out of change detection.

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

For scheduled runs: track listings between runs and return only NEW or CHANGED ones (UNCHANGED rows are suppressed unless Emit unchanged is on). Price, availability and detail changes (see Change scope) drive UPDATED; scrape time, change labels and the order of reviews or photos never do. Cannot be combined with Resume from run ID.

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

Advanced: name of the incremental baseline. Leave empty to derive it from your search scope automatically (recommended).

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

Incremental mode: also return listings that did not change since the last run (labelled UNCHANGED).

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

Incremental mode: label listings that disappeared from the results since the last complete run as EXPIRED.

## `compactUpdates` (type: `boolean`):

Incremental mode: return UPDATED and EXPIRED listings as slim rows (identifiers, current price and availability, plus priceChanges and variantChanges with the old and new values) instead of the full record. NEW listings stay full. A slim UPDATED row is billed for the availability read only, never for the detail record or reviews it no longer carries. Off by default.

## `expireAfterMissedScans` (type: `integer`):

With Emit expired: a listing is labelled EXPIRED only after it was missing from this many complete scans in a row (1 = the first complete scan that misses it). EXPIRED means the listing no longer appears in the results, not that it is unavailable for your dates: check busyStatus and roomsAvailable for availability.

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

Advanced: dataset field names that should not mark a listing as CHANGED in incremental mode (e.g. fields you find too volatile for your schedule). A dotted path such as seasonPrices.type drops that key from every element of the list while the rest of each element is still compared.

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

Send results into your apps (MCP connectors). Leave empty to only use the dataset. See the README for the connector config shape.

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

URL (or id) of the Notion page under which listing 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
{
  "mode": "search",
  "location": "Санкт-Петербург",
  "guestsAdults": 2,
  "guestsChildrens": [],
  "pets": false,
  "sortings": "relevance",
  "maxItems": 20,
  "maxPages": 0,
  "housingTypes": [],
  "stars": [],
  "minReviewScores": [],
  "bookingNow": false,
  "urls": [
    {
      "url": "https://sochi.sutochno.ru/998663"
    },
    {
      "url": "https://sutochno.ru/front/searchapp/detail/858763"
    },
    {
      "url": "https://sutochno.ru/hotels/144264"
    },
    {
      "url": "https://sutochno.ru/hotels/144264?occupied=2026-12-10;2026-12-13"
    },
    {
      "url": "https://sutochno.ru/front/searchapp/search?term=%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3&guests_adults=2"
    },
    {
      "url": "https://sutochno.ru/front/searchapp/search?term=%D0%A1%D0%BE%D1%87%D0%B8&occupied=2026-12-10;2026-12-13&guests_adults=2&sortings=1"
    },
    {
      "url": "https://sutochno.ru/front/searchapp/search?term=Sochi&page=2&guests_adults=2"
    },
    {
      "url": "https://sutochno.ru/front/searchapp/search?is_hotel=1&guests_adults=2&id=397367&type=city&term=%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3"
    },
    {
      "url": "https://spb.sutochno.ru/"
    },
    {
      "url": "https://spb.sutochno.ru/?page=2"
    },
    {
      "url": "https://spb.sutochno.ru/1-komnatnye"
    },
    {
      "url": "https://spb.sutochno.ru/hotels"
    },
    {
      "url": "https://sutochno.ru/armenia"
    },
    {
      "url": "https://sutochno.ru/998663"
    },
    {
      "url": "https://m.sutochno.ru/998663"
    }
  ],
  "fetchDetails": true,
  "fetchReviews": true,
  "maxReviews": 20,
  "fetchAvailability": true,
  "availabilityDays": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "changeScope": "all",
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "compactUpdates": false,
  "expireAfterMissedScans": 1,
  "ignoreFieldsForChanges": [],
  "mcpConnectors": [],
  "maxNotifyListings": 50
}
```

# Actor output Schema

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

One row per listing: title, price, stay totals, rating, location, capacity and booking flags.

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

Listing records with every detail field: house rules, amenities, owner profile, season and long-stay pricing, availability.

## `reviews` (type: `string`):

One row per guest review (unwound from the listing records) when review collection is on.

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

Incremental mode: change type, changed fields and first/last seen per listing.

# 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",
    "location": "Санкт-Петербург",
    "guestsAdults": 2,
    "sortings": "relevance",
    "maxItems": 20,
    "maxPages": 0,
    "urls": [
        {
            "url": "https://sochi.sutochno.ru/998663"
        },
        {
            "url": "https://sutochno.ru/front/searchapp/detail/858763"
        },
        {
            "url": "https://sutochno.ru/hotels/144264"
        },
        {
            "url": "https://sutochno.ru/hotels/144264?occupied=2026-12-10;2026-12-13"
        },
        {
            "url": "https://sutochno.ru/front/searchapp/search?term=%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3&guests_adults=2"
        },
        {
            "url": "https://sutochno.ru/front/searchapp/search?term=%D0%A1%D0%BE%D1%87%D0%B8&occupied=2026-12-10;2026-12-13&guests_adults=2&sortings=1"
        },
        {
            "url": "https://sutochno.ru/front/searchapp/search?term=Sochi&page=2&guests_adults=2"
        },
        {
            "url": "https://sutochno.ru/front/searchapp/search?is_hotel=1&guests_adults=2&id=397367&type=city&term=%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3"
        },
        {
            "url": "https://spb.sutochno.ru/"
        },
        {
            "url": "https://spb.sutochno.ru/?page=2"
        },
        {
            "url": "https://spb.sutochno.ru/1-komnatnye"
        },
        {
            "url": "https://spb.sutochno.ru/hotels"
        },
        {
            "url": "https://sutochno.ru/armenia"
        },
        {
            "url": "https://sutochno.ru/998663"
        },
        {
            "url": "https://m.sutochno.ru/998663"
        }
    ],
    "fetchDetails": true,
    "fetchReviews": true,
    "maxReviews": 20,
    "fetchAvailability": true,
    "availabilityDays": 30,
    "proxyConfiguration": {
        "useApifyProxy": true
    },
    "changeScope": "all",
    "incrementalMode": false,
    "compactUpdates": false,
    "expireAfterMissedScans": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/sutochno-ru-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",
    "location": "Санкт-Петербург",
    "guestsAdults": 2,
    "sortings": "relevance",
    "maxItems": 20,
    "maxPages": 0,
    "urls": [
        { "url": "https://sochi.sutochno.ru/998663" },
        { "url": "https://sutochno.ru/front/searchapp/detail/858763" },
        { "url": "https://sutochno.ru/hotels/144264" },
        { "url": "https://sutochno.ru/hotels/144264?occupied=2026-12-10;2026-12-13" },
        { "url": "https://sutochno.ru/front/searchapp/search?term=%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3&guests_adults=2" },
        { "url": "https://sutochno.ru/front/searchapp/search?term=%D0%A1%D0%BE%D1%87%D0%B8&occupied=2026-12-10;2026-12-13&guests_adults=2&sortings=1" },
        { "url": "https://sutochno.ru/front/searchapp/search?term=Sochi&page=2&guests_adults=2" },
        { "url": "https://sutochno.ru/front/searchapp/search?is_hotel=1&guests_adults=2&id=397367&type=city&term=%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3" },
        { "url": "https://spb.sutochno.ru/" },
        { "url": "https://spb.sutochno.ru/?page=2" },
        { "url": "https://spb.sutochno.ru/1-komnatnye" },
        { "url": "https://spb.sutochno.ru/hotels" },
        { "url": "https://sutochno.ru/armenia" },
        { "url": "https://sutochno.ru/998663" },
        { "url": "https://m.sutochno.ru/998663" },
    ],
    "fetchDetails": True,
    "fetchReviews": True,
    "maxReviews": 20,
    "fetchAvailability": True,
    "availabilityDays": 30,
    "proxyConfiguration": { "useApifyProxy": True },
    "changeScope": "all",
    "incrementalMode": False,
    "compactUpdates": False,
    "expireAfterMissedScans": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/sutochno-ru-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",
  "location": "Санкт-Петербург",
  "guestsAdults": 2,
  "sortings": "relevance",
  "maxItems": 20,
  "maxPages": 0,
  "urls": [
    {
      "url": "https://sochi.sutochno.ru/998663"
    },
    {
      "url": "https://sutochno.ru/front/searchapp/detail/858763"
    },
    {
      "url": "https://sutochno.ru/hotels/144264"
    },
    {
      "url": "https://sutochno.ru/hotels/144264?occupied=2026-12-10;2026-12-13"
    },
    {
      "url": "https://sutochno.ru/front/searchapp/search?term=%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3&guests_adults=2"
    },
    {
      "url": "https://sutochno.ru/front/searchapp/search?term=%D0%A1%D0%BE%D1%87%D0%B8&occupied=2026-12-10;2026-12-13&guests_adults=2&sortings=1"
    },
    {
      "url": "https://sutochno.ru/front/searchapp/search?term=Sochi&page=2&guests_adults=2"
    },
    {
      "url": "https://sutochno.ru/front/searchapp/search?is_hotel=1&guests_adults=2&id=397367&type=city&term=%D0%A1%D0%B0%D0%BD%D0%BA%D1%82-%D0%9F%D0%B5%D1%82%D0%B5%D1%80%D0%B1%D1%83%D1%80%D0%B3"
    },
    {
      "url": "https://spb.sutochno.ru/"
    },
    {
      "url": "https://spb.sutochno.ru/?page=2"
    },
    {
      "url": "https://spb.sutochno.ru/1-komnatnye"
    },
    {
      "url": "https://spb.sutochno.ru/hotels"
    },
    {
      "url": "https://sutochno.ru/armenia"
    },
    {
      "url": "https://sutochno.ru/998663"
    },
    {
      "url": "https://m.sutochno.ru/998663"
    }
  ],
  "fetchDetails": true,
  "fetchReviews": true,
  "maxReviews": 20,
  "fetchAvailability": true,
  "availabilityDays": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "changeScope": "all",
  "incrementalMode": false,
  "compactUpdates": false,
  "expireAfterMissedScans": 1
}' |
apify call abotapi/sutochno-ru-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/sutochno-ru-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/gmx24kokWd1h6xvam/builds/dRl1KMGyJ6HMoByTY/openapi.json
