# Booli Scraper - Swedish Listings, Sold Prices & Agents (`lentic_clockss/booli-scraper`) Actor

Collect Swedish property listings, sold prices, new construction, agents, agencies and housing cooperatives from Booli. Export structured rows and pay per delivered row plus a start fee.

- **URL**: https://apify.com/lentic_clockss/booli-scraper.md
- **Developed by:** [kane liu](https://apify.com/lentic_clockss) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Features:** Limited permissions
- **Stats:** 15 total users, 4 monthly users, 98.4% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.20 / 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

**Collect Swedish property listings, sold prices, projects, agents and housing cooperatives from Booli as rows you can export.**

- Asking prices, sold prices, property sizes and source links.
- Area searches and specific Booli detail URLs.
- Public agent contacts when available, with reasons for missing fields.
- JSON, CSV and Excel exports for research or recurring reports.
- $3.00 per 1,000 rows on the Free plan, plus a small start fee.

### What does Booli Scraper do?

Booli Scraper collects public real-estate data from Booli.se in Sweden. Compare asking and sold prices, track new construction or collect agent information. Each row represents a listing, sold property, project, agent, agency or housing cooperative; `rowType` distinguishes them.

- **For sale:** `till-salu` searches active listings.
- **Sold prices:** `slutpriser` searches sale history with optional dates.
- **New construction:** `nyproduktion` searches new-build properties and projects.
- **Agents:** `maklare` searches agents by area.
- **Agencies:** `maklarbyra` collects an agency's agents from its slug, or agency records from agency pages.
- **Housing cooperatives:** `brf` collects associations from detail URLs or discovers them through area listings.

`enrichDetails` is on by default and adds available property details and public agent contacts to listing rows. `enrichHousingCoop` is off by default; standard listing results provide only the available cooperative ID, name and link, not a complete association profile. These options enrich existing rows rather than adding a separately priced event.

### What data can you extract from Booli?

Fields vary by row type and source availability. `rowType` identifies the row category; `type` holds the property or entity type. Missing values remain empty.

#### Listings: `listing`

| Field | Description | Example |
| --- | --- | --- |
| `listingId` | Booli identifier | `1234567` |
| `listingUrl` | Source page | `https://www.booli.se/annons/1234567` |
| `name` | Property name or address label | `Example Street 12` |
| `streetAddress` | Street and house number | `Example Street 12` |
| `descriptiveAreaName` | Neighborhood or area | `Stockholm` |
| `listPrice` | Asking price in SEK | `4950000` |
| `priceDisplay` | Formatted asking price | `4 950 000 kr` |
| `rooms` | Number of rooms | `3` |
| `livingArea` | Living space in square meters | `75` |
| `objectType` | Property category | `Lägenhet` |
| `tenureForm` | Ownership form | `Bostadsrätt` |
| `geo` | Latitude and longitude | `{"lat":59.33,"lng":18.06}` |
| `images` | Image URLs, capped by `imageLimit` | `[]` |

#### Sold properties: `sold`

| Field | Description | Example |
| --- | --- | --- |
| `soldPrice` | Recorded sale price in SEK | `5100000` |
| `soldDate` | Source sale date | `2026-09-15` |
| `soldSqmPrice` | Sale price per square meter | `68000` |
| `soldPriceType` | Source's sale-price classification | `null` |

#### New construction: `project`

| Field | Description | Example |
| --- | --- | --- |
| `isNewConstruction` | New-build indicator | `true` |
| `phase` | Project phase, when supplied | `null` |
| `listPriceRange` | Available project price range | `null` |

#### Agents: `agent`

| Field | Description | Example |
| --- | --- | --- |
| `agentSlug` | Profile identifier | `jane.doe` |
| `agencyName` | Associated agency | `Example Agency` |
| `phones` | Available public telephone numbers | `[{"value":"+46 555 0100","type":"work"}]` |
| `emails` | Available public email addresses | `[{"value":"name@example.com","type":"work"}]` |
| `leadAbsences` | Reasons contact fields are empty | `{}` |

#### Agencies: `agency`

| Field | Description | Example |
| --- | --- | --- |
| `agencySlug` | Agency page identifier | `example-agency` |
| `profileUrl` | Agency source page | `https://www.booli.se/maklarbyra/example-agency` |

#### Housing cooperatives: `housing_coop`

| Field | Description | Example |
| --- | --- | --- |
| `housingCoopId` | Association identifier | `47201` |
| `orgNumber` | Published organization number | `null` |
| `residenceCount` | Reported number of homes | `42` |

Sold and project rows also carry available property fields. Entity rows include `name` and source links. `leadAbsences` gives a reason, `not_on_list_page` (a search card; the agent or listing page carries it) or `not_verified` (often with a note), for each empty contact field except `web.website`, which Booli rows never fill.

### How to scrape Booli

1. Open [Booli Scraper](https://apify.com/lentic_clockss/booli-scraper) in Apify Console.
2. Enter `location`, `areaIds` or `detailUrls`, and choose `channel`.
3. Set `maxResults` to `3` for a small first run.
4. Click **Start** and wait for completion.
5. Download the dataset or read it through the API.

Empty input starts an example run for Stockholms län (`areaIds: [2]`), with `channel: "till-salu"` and at most 3 rows. Normal event prices still apply. A target field selects search or detail collection; it does not infer the channel. Choose `channel` explicitly for anything other than for-sale listings.

#### For-sale listings

Use `till-salu` with a Swedish location or area IDs. Add price, room or size filters as needed.

#### Sold prices

Use `slutpriser`. Set `minSoldDate` and `maxSoldDate` if needed; leaving them blank does not create a date window.

#### New construction

Use `nyproduktion` with an area. Results depend on available new-build listings and projects.

#### Agents

Use `maklare` with a location. Area results are not a complete national agent directory.

#### Agencies

For an agency's agent roster, set `maklarbyra` and put its agency slug, not a place name, in `areaSlug` or `location`. Explicit agency `detailUrls` return agency records instead. Without an agency slug or URLs, this channel uses the national agency index.

#### Housing cooperatives and direct URLs

Use `brf` with association URLs, or an area to discover associations linked to listings. Other supported detail paths include `/annons/`, `/bostad/`, `/maklare/` and `/maklarbyra/`; choose the matching channel. Detail URLs take priority over search fields. Use one target form at a time to avoid ambiguity.

### What to fill in

| Field | What to enter | Default |
| --- | --- | --- |
| `location` | Swedish place name, such as `Lund` | Empty |
| `areaIds` | Booli area IDs; `[2]` is Stockholms län | Example only: `[2]` |
| `areaSlug` | Place slug, or agency slug for `maklarbyra` | Empty |
| `detailUrls` | Booli detail URLs or listing IDs | Empty |
| `channel` | One of the six channels above | `till-salu` |
| `objectType` / `tenureForm` | For example `Lägenhet` / `Bostadsrätt` | Empty |
| `minListPrice` / `maxListPrice` | Asking-price bounds in SEK | Unset |
| `minSoldPrice` / `maxSoldPrice` | Sale-price bounds in SEK | Unset |
| `minRooms` / `maxRooms` | Room-count bounds | Unset |
| `minLivingArea` / `maxLivingArea` | Living-area bounds in square meters | Unset |
| `minPlotArea` / `maxPlotArea` | Plot-area bounds in square meters | Unset |
| `minConstructionYear` / `maxConstructionYear` | Year bounds, `1600`–`2100` | Unset |
| `minSoldDate` / `maxSoldDate` | `YYYY-MM-DD` or `YYYYMMDD` | Unset |
| `isNewConstruction` | Restrict listings to new construction | Unset |
| `sort` / `ascending` | Sort field, such as `soldDate`, and direction | Empty / `false` |
| `maxResults` | Rows per input, `1`–`500` | `70`; form example `3` |
| `maxPages` | Search-page limit, `1`–`50` | `1` |
| `pageSize` | Rows requested per page, `1`–`500` | `100` |
| `enrichDetails` | Include available listing details and contacts | `true` |
| `enrichHousingCoop` | Include available cooperative context | `false` |
| `imageLimit` | Maximum images per listing, `0`–`20` | `5` |
| `includeRaw` | Attach available source data | `false` |

For sale:

```json
{"location":"Lund","channel":"till-salu","maxResults":3}
```

Sold prices:

```json
{"location":"goteborg","channel":"slutpriser","sort":"soldDate","maxResults":3}
```

New construction:

```json
{"areaIds":[2],"channel":"nyproduktion","maxResults":3}
```

Agents:

```json
{"location":"stockholm","channel":"maklare","maxResults":3}
```

An agency's agents:

```json
{"areaSlug":"fastighetsbyran","channel":"maklarbyra","maxResults":3}
```

Housing cooperative detail:

```json
{"detailUrls":["https://www.booli.se/bostadsrattsforening/47201"],"channel":"brf","maxResults":1}
```

Specific listing:

```json
{"detailUrls":["https://www.booli.se/annons/1234567"],"channel":"till-salu","maxResults":1}
```

The last listing ID illustrates the format; replace it with your target. For listing and agent searches, `location` or `areaSlug` takes precedence over area IDs. `sale`, `sold`, `projects` and `agents` are channel aliases.

- `maxItems` and `limit` are aliases of `maxResults`; `urls` and `startUrls` map to `detailUrls`, and `place` and `city` map to `location`.
- Close field-name misspellings can be corrected; other unknown fields are ignored. Unreadable filters may be dropped with a note.
- Invalid targets and unknown channels stop collection with `INVALID_INPUT:`, followed by the field and accepted format. No rows are charged; the start fee can still apply.
- `INPUT_REPORT` in the run's key-value store records filled, corrected and ignored input fields. `RUN_SUMMARY` records counts and warnings; failures can also write `ERROR_SUMMARY`.

### Output example

Illustrative listing row; the address and ID are placeholders:

```json
{
  "name": "Example Street 12, Stockholm",
  "type": "Lägenhet",
  "rowType": "listing",
  "status": "for_sale",
  "country": "SE",
  "authority": "booli.se",
  "channel": "till-salu",
  "listingId": "1234567",
  "listingUrl": "https://www.booli.se/annons/1234567",
  "streetAddress": "Example Street 12",
  "descriptiveAreaName": "Stockholm",
  "listPrice": 4950000,
  "priceDisplay": "4 950 000 kr",
  "rooms": 3,
  "livingArea": 75,
  "phones": [],
  "emails": [],
  "leadAbsences": {}
}
```

Export the dataset as JSON, CSV, Excel, XML, RSS or an HTML table.

### Why use this Booli scraper?

- **Row-based billing:** row charges cover delivered rows, not attempted pages; a start fee also applies.
- **Partial results:** when collection stops with rows available, the Actor delivers those rows and records warnings. Rows already written remain in the dataset; a forced stop before delivery can leave it empty.
- **Missing data stays missing:** unavailable contacts are not invented.
- **Several inputs:** supply multiple area IDs or detail URLs; duplicate identifiers are removed.
- **No proxy setup:** you do not need to set up proxies or supply a Booli account.

### How much does it cost to scrape Booli?

Pay-per-event pricing includes platform usage. The start event costs **$0.005**, charged per GB of allocated memory with a minimum of one event. At the default **512 MB**, that is one event: **$0.005**.

| Apify plan | Price per row | Price per 1,000 rows |
| --- | --- | --- |
| Free | $0.003 | $3.00 |
| Starter | $0.003 | $3.00 |
| Scale | $0.0026 | $2.60 |
| Business | $0.0022 | $2.20 |
| Platinum | $0.002 | $2.00 |
| Diamond | $0.0016 | $1.60 |

`maxResults` applies to each area, location or detail URL. Its default is 70; larger requests are collected in parts of 70, up to the input maximum of 500. All row types count toward the limit. Fewer matches, page limits or unavailable pages can reduce delivery.

The Free plan is limited to **200 rows per run and 10 runs of this Actor**, set by the publisher. The whole run also stops at **Maximum cost per run** (`maxTotalChargeUsd` in the API).

Example: 2 areas delivering 5 rows each means 10 rows. On the Free plan at 512 MB, one start plus those rows costs `10 × $0.003 + $0.005 = $0.035`.

- The Apify Free plan includes **$5.00** in monthly usage credit (about **1,666 rows** at `$0.003` per row across Free-plan runs capped at 200 rows per run).

### What happens when the run timeout is too short

If there is too little time to finish, the run can pause with the message "Queued on the collection backend; this run will resume automatically when results are ready (about N s)." It temporarily shows `ABORTED`, rather than a collection failure.

When results are ready, the same run restarts automatically, reports "Resumed: delivering N rows.", writes to the same dataset and finishes as `SUCCEEDED`. Already delivered rows are skipped, not delivered or charged twice. This can happen at most 3 times per run. Keep the default **3600-second** timeout to reduce pauses.

The synchronous API endpoints (`run-sync`, `run-sync-get-dataset-items`) wait at most 300 seconds and can return an empty dataset during a pause. For longer searches, start asynchronously and read the dataset after `SUCCEEDED`, or use a succeeded-event webhook.

### Use with AI agents and the API

#### Apify MCP server

Add this remote server in Claude, ChatGPT, Cursor, VS Code or another compatible MCP client:

```text
https://mcp.apify.com?tools=lentic_clockss/booli-scraper
```

Sign in with Apify through OAuth, or send `Authorization: Bearer <YOUR_APIFY_TOKEN>`. The tool starts a run and returns run and dataset IDs; read the rows with `get-dataset-items`. Clients without remote-server support can use `npx @apify/actors-mcp-server --tools lentic_clockss/booli-scraper` with `APIFY_TOKEN` set.

Example prompt: "Find three homes for sale in Lund using Booli Scraper and show their asking prices and links."

- **Agent execution note:** Set `maxResults` between `5` and `20` on exploratory tool calls to keep responses compact, and read `RUN_SUMMARY` and `INPUT_REPORT` from the default key-value store to inspect normalized inputs and delivered row counts. When a long run briefly reports `ABORTED` with the automatic-resume status message, wait for the same run ID to finish as `SUCCEEDED` instead of starting a duplicate run.

#### Apify API

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("lentic_clockss/booli-scraper").call(
    run_input={"location": "Lund", "channel": "till-salu", "maxResults": 3}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

JavaScript:

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('lentic_clockss/booli-scraper').call({
  location: 'Lund', channel: 'till-salu', maxResults: 3
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

For HTTP, send the input as JSON to `POST https://api.apify.com/v2/acts/lentic_clockss~booli-scraper/runs` with an `Authorization: Bearer <YOUR_APIFY_TOKEN>` header. After completion, read `GET https://api.apify.com/v2/datasets/<datasetId>/items?format=json`.

#### Integrations

Use the **Integrations** tab for Google Sheets, Make, Zapier, n8n, Slack, Airtable or webhooks. Apify Schedules can run the same saved input regularly.

### På svenska

Booli Scraper samlar offentliga bostadsuppgifter från Booli i Sverige. Du kan hämta bostäder till salu, slutpriser, nyproduktion, mäklare och bostadsrättsföreningar. Skriv en ort i `location`, ange områden med `areaIds` eller klistra in länkar i `detailUrls`. Välj rätt kategori med `channel` och börja gärna med `maxResults` satt till tre. Resultaten kan laddas ned som Excel, CSV eller JSON. Priset består av en startavgift och en avgift per levererad rad. Kontaktuppgifter följer bara med när de finns tillgängliga; tomma fält betyder inte att uppgifterna saknas överallt. Kontrollera därför källan innan du använder uppgifterna för jämförelser eller kontakt med en mäklare. Användningen måste följa tillämpliga villkor och dataskyddsregler.

### FAQ

#### Is it legal to scrape Booli?

The Actor collects public information. You are responsible for checking Booli's terms and applicable data-protection law. Personal data needs a lawful basis for collection and use; public visibility alone is not permission for every use.

#### Why did my run end as ABORTED?

Check the status message. The automatic-resume message means a temporary pause; a manually aborted run is not the same. See the timeout section above.

#### How many results can I get?

Set `maxResults` from 1 to 500 per input. Delivery also depends on matching records, page limits, your cost cap and Free-plan limits.

#### Why are some fields empty?

Booli does not publish every field on every surface. Search-only listings may lack contacts, and detail collection can fail. Check `leadAbsences` and run warnings.

#### Why does the no-rows failure message read differently from earlier runs?

From the Actor version published on 2026-11-13, a run that fails because no rows were collected shows a status message starting with `No Booli rows were collected.`, followed by up to five run warnings or, when there are none, `Check areaIds / channel.`. Earlier messages began with `No Booli rows` and the fallback hint was `Check areaIds / channel / proxy.`

#### Why do some `leadAbsences` reasons read `not_verified` instead of `Not on source`?

From 13 November 2026, three reasons no longer say that Booli lacks a field, because the parser cannot confirm the page has none. They appear only on rows with detail-page data: listings filled from the listing page (listing URLs in `detailUrls`, or search results with `enrichDetails`, the default), agency pages (`/maklarbyra/`) and housing cooperative pages.

| Key | Row | Earlier | Now |
|---|---|---|---|
| `org` | Listing with listing-page data and no agency | `"Not on source: listing page lists no agency or organization"` | `not_verified (no agency name or id found on the listing page)` |
| `address` | Agency page | `"Not on source: agency page lists no street address"` | `not_verified (the agency page parser reads only an area name, and this agency has none)` |
| `address` | Housing cooperative page | `"Not on source: housing coop page lists no street address"` | `not_verified (no street address or area name found on the housing coop page)` |

These rows no longer carry `quality.missingFields.org` or `quality.missingFields.address` = `not_present`, or the matching `quality.evidence` entry. Other reasons, including `web_socials` and the search-card `not_on_list_page` codes, are unchanged.

#### Can I collect both asking and sold prices?

Use separate runs with `till-salu` and `slutpriser`, then combine the datasets if needed.

#### Does it collect listing details and full BRF profiles?

Listing enrichment is enabled by default. Cooperative context in standard listing results is limited to available IDs, names and links; use `brf` for association records, which can still have missing fields.

#### Do I need a Booli API key?

No Booli API key is required. Use your Apify token for API access to this Actor; it is not an official Booli API.

### Limitations

- Sweden only; no separate rental-search channel. `Hyresrätt` is a tenure filter, not a rental mode.
- Not every Booli URL is supported. Office `/maklarkontor/` and project `/projekt/` detail URLs are not supported targets; search new construction by area instead.
- Agent-area results are a selection, not guaranteed exhaustive coverage.
- Agency pages and BRF records may lack contacts. No contact forms are submitted.
- `enrichHousingCoop` does not guarantee organization numbers or residence counts for listing rows.
- Unavailable pages can cause failures or partial results. A successful empty search is not proof that an entire area has no properties.

### Related scrapers

More real estate and property data scrapers from the same publisher:

- [Zumper Scraper](https://apify.com/lentic_clockss/us-real-estate-scraper)
- [Craigslist Scraper](https://apify.com/lentic_clockss/craigslist-housing-scraper)
- [PropertyGuru Scraper](https://apify.com/lentic_clockss/propertyguru-sg-scraper)
- [OpenSooq Scraper](https://apify.com/lentic_clockss/opensooq-real-estate-scraper)
- [Apartments.com Scraper](https://apify.com/lentic_clockss/apartments-com-rental-scraper)
- [Dot Property Scraper](https://apify.com/lentic_clockss/dot-property-th-scraper)
- [Email Validator](https://apify.com/lentic_clockss/email-risk-validator)
- [Phone Number Validator](https://apify.com/lentic_clockss/phone-number-intelligence)

Browse all of our scrapers at [apify.com/lentic_clockss](https://apify.com/lentic_clockss).

### Support

Found a problem or need another field? Open an issue in the **Issues** tab of this Actor's page and include the run ID and the input you used.

# Actor input Schema

## `areaIds` (type: `array`):

Booli area IDs to search. The example value \[2] selects Stockholms län; repeated properties across areas are removed.

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

Swedish place name or slug, such as Lund or goteborg. For listing and agent searches, this takes precedence over areaIds.

## `areaSlug` (type: `string`):

Place slug for area searches. With channel maklarbyra, enter an agency slug instead to collect its agents.

## `detailUrls` (type: `array`):

Booli detail URLs or listing IDs. Match channel to the target: property, agent, agency or housing cooperative; these targets take priority over area searches.

## `channel` (type: `string`):

Choose for-sale listings, sold prices, new construction, agents, agencies or housing cooperatives. An agency slug with maklarbyra returns that agency's agents.

## `objectType` (type: `string`):

Property category to match, such as Lägenhet (apartment), Villa (house), Radhus (terraced house) or Tomt/Mark (land). Leave empty for all categories.

## `tenureForm` (type: `string`):

Ownership form to match, such as Bostadsrätt (cooperative ownership), Äganderätt (freehold) or Hyresrätt (rental tenure). This is not a separate rental-search mode.

## `minListPrice` (type: `integer`):

Minimum asking price in SEK for listing searches.

## `maxListPrice` (type: `integer`):

Maximum asking price in SEK for listing searches.

## `minSoldPrice` (type: `integer`):

Minimum sale price in SEK for sold-property searches.

## `maxSoldPrice` (type: `integer`):

Maximum sale price in SEK for sold-property searches.

## `minRooms` (type: `number`):

Minimum room count for property searches.

## `maxRooms` (type: `number`):

Maximum room count for property searches.

## `minLivingArea` (type: `integer`):

Optional minimum living area in square meters.

## `maxLivingArea` (type: `integer`):

Optional maximum living area in square meters.

## `minPlotArea` (type: `integer`):

Optional minimum plot area in square meters.

## `maxPlotArea` (type: `integer`):

Optional maximum plot area in square meters.

## `minConstructionYear` (type: `integer`):

Earliest construction year to include, from 1600 to 2100.

## `maxConstructionYear` (type: `integer`):

Latest construction year to include, from 1600 to 2100.

## `minSoldDate` (type: `string`):

Earliest sale date for slutpriser. Use YYYY-MM-DD or YYYYMMDD; leave empty for no lower date bound.

## `maxSoldDate` (type: `string`):

Latest sale date for slutpriser. Use YYYY-MM-DD or YYYYMMDD; leave empty for no upper date bound.

## `isNewConstruction` (type: `boolean`):

When true, only include new construction listings.

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

Sort field, such as listPrice, published, livingArea, rooms, soldPrice, soldDate or listSqmPrice. Leave empty for the source order.

## `ascending` (type: `boolean`):

Use ascending order when a sort field is set.

## `maxResults` (type: `integer`):

Most rows for each area, location, or detail URL. Default 70; larger numbers are collected in parts of 70. All row types count together. The whole run stops at your maximum total charge. Free Apify plan: up to 200 rows per run and 10 runs of this Actor (limits set by the Actor developer).

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

Maximum search pages to collect, from 1 to 50. A low page limit can return fewer rows than maxResults.

## `pageSize` (type: `integer`):

Rows requested per search page, from 1 to 500. This stays fixed during pagination; maxResults limits delivered rows per input.

## `enrichDetails` (type: `boolean`):

Include available property details and public agent contacts in listing rows. Enabled by default; missing contacts remain empty.

## `enrichHousingCoop` (type: `boolean`):

Include available housing-cooperative context in listing rows. Standard listing results contain only the available ID, name and link, not a complete association profile.

## `imageLimit` (type: `integer`):

Maximum image URLs per listing, from 0 to 20. Set 0 to omit images.

## `includeRaw` (type: `boolean`):

Attach available source data to each row. Disabled by default; enabling it can increase row size.

## `provider` (type: `string`):

Leave empty. Used only by the developer for testing.

## `workerBaseUrl` (type: `string`):

Leave empty. Used only by the developer for testing.

## Actor input object example

```json
{
  "areaIds": [
    2
  ],
  "channel": "till-salu",
  "objectType": "",
  "tenureForm": "",
  "sort": "",
  "ascending": false,
  "maxResults": 3,
  "maxPages": 1,
  "pageSize": 100,
  "enrichDetails": true,
  "enrichHousingCoop": false,
  "imageLimit": 5,
  "includeRaw": false,
  "workerBaseUrl": ""
}
```

# Actor output Schema

## `listings` (type: `string`):

Dataset containing Booli listings, sold properties, projects, agents, agencies or housing cooperatives, depending on the selected channel.

# 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 = {
    "areaIds": [
        2
    ],
    "channel": "till-salu",
    "objectType": "",
    "tenureForm": "",
    "sort": "",
    "maxResults": 3,
    "maxPages": 1,
    "pageSize": 100,
    "enrichDetails": true,
    "enrichHousingCoop": false,
    "imageLimit": 5,
    "includeRaw": false,
    "workerBaseUrl": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("lentic_clockss/booli-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 = {
    "areaIds": [2],
    "channel": "till-salu",
    "objectType": "",
    "tenureForm": "",
    "sort": "",
    "maxResults": 3,
    "maxPages": 1,
    "pageSize": 100,
    "enrichDetails": True,
    "enrichHousingCoop": False,
    "imageLimit": 5,
    "includeRaw": False,
    "workerBaseUrl": "",
}

# Run the Actor and wait for it to finish
run = client.actor("lentic_clockss/booli-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 '{
  "areaIds": [
    2
  ],
  "channel": "till-salu",
  "objectType": "",
  "tenureForm": "",
  "sort": "",
  "maxResults": 3,
  "maxPages": 1,
  "pageSize": 100,
  "enrichDetails": true,
  "enrichHousingCoop": false,
  "imageLimit": 5,
  "includeRaw": false,
  "workerBaseUrl": ""
}' |
apify call lentic_clockss/booli-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lentic_clockss/booli-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/MYUkrCm3jFeX82RpJ/builds/0tkpRPH6wX2HihAvT/openapi.json
