# PanoramaFirm Scraper: Polish Business Phones & Emails (`themineworks/panoramafirm-business-email-scraper`) Actor

Scrape PanoramaFirm.pl by trade and town: business name, phone, address, website, rating and NIP. Turn on emails to get the address the business published on the card or its own website, charged only when found. Pay per business.

- **URL**: https://apify.com/themineworks/panoramafirm-business-email-scraper.md
- **Developed by:** [The Mine Works](https://apify.com/themineworks) (community)
- **Categories:** Lead generation, Business, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 business listings

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

## PanoramaFirm Scraper: Polish Business Phones & Emails

[![20 Warsaw plumbers, 16 emails, 14 seconds](https://api.apify.com/v2/key-value-stores/cUXz95yxflDho41nn/records/panoramafirm-business-email-scraper-hero.png)](https://console.apify.com/actors/EnLrE5ClJuGz3NHj1/input)

From **The Mine Works**, makers of [Threads Scraper](https://apify.com/themineworks/threads-scraper) and [B2B Leads Finder](https://apify.com/themineworks/b2b-leads-finder), with over 140,000 runs across 170+ public actors.

Type a trade in Polish and a place in Poland, for example `hydraulik` in `Warszawa`, and get one row per business that PanoramaFirm.pl lists: name, phone in international format, address with postcode, coordinates, Warsaw district, website, rating and review count, and the link to its PanoramaFirm page. Turn on **Find emails** and the actor adds the email address the business published on PanoramaFirm, or else one read from its own website. Open each business page and you also get the Polish NIP tax number.

### Why choose this actor?

- **Most emails come straight from the directory, charged only when delivered.** PanoramaFirm keeps the business's email in each result card, so in our proof run (hydraulik in Warszawa, 28 Sep 2026) **16 of 20 businesses came back with an email** without visiting a single company website. The other 4 had no email and no website, and were charged as businesses only.
- **The NIP tax number for every business page we opened.** With business pages on, our 1 Oct 2026 run of 25 dentists in Kraków returned the NIP for all 25, plus 19 emails, in 17 seconds. Match it against Poland's business registers or your CRM.
- **No nationwide rows billed under a town's name.** PanoramaFirm quietly drops a place it does not know (a postcode, a typo) and searches all of Poland instead. The actor spots that and returns nothing for that search, with a note in the run summary. No account, cookies or API key.

[![Run it on Apify](https://api.apify.com/v2/key-value-stores/cUXz95yxflDho41nn/records/button-run.png)](https://console.apify.com/actors/EnLrE5ClJuGz3NHj1/input)

**Part of The Mine Works Leads and business directories family:** [B2B Leads Finder](https://apify.com/themineworks/b2b-leads-finder), [Skip Trace Lookup](https://apify.com/themineworks/skip-trace-lookup), [Google Maps Email Scraper](https://apify.com/themineworks/maps-leads), [JustDial Scraper](https://apify.com/themineworks/justdial-business), [2GIS Places Scraper](https://apify.com/themineworks/2gis-places-search), [IndiaMART Scraper](https://apify.com/themineworks/indiamart-suppliers).

### Try it in one minute

Paste this input into the JSON tab and press Start. It returns the first 10 plumbers PanoramaFirm lists for Warsaw, without emails, in a few seconds:

```json
{
  "queries": ["hydraulik"],
  "locations": ["Warszawa"],
  "maxResultsPerSearch": 10
}
```

You can say what you want in two ways, and mix them in one run:

- **Queries and locations** (`queries`, `locations`): Polish trade words as you would type them on the site, such as `hydraulik`, `elektryk`, `dentysta`, `fryzjer` or `restauracja`, and a city, county, voivodeship or Warsaw district (`Kraków`, `mazowieckie`, `Mokotów`). Every query is searched in every location. Leave `locations` empty to search the whole country. Postcodes are not recognised by the site.
- **Search pages** (`startUrls`): a PanoramaFirm results page copied from your browser, either `https://panoramafirm.pl/szukaj?what=hydraulik&where=Warszawa` or the short form the site redirects to, such as `https://panoramafirm.pl/hydraulik/mazowieckie,,warszawa`.

API and agent callers can also use other common field names: `query`, `keyword`, `keywords` or `searchTerms` for queries, `location`, `where` or `city` for locations, `urls` for search pages, `maxResults` or `maxItems` for the limit, and `sort` for `sortBy`.

Apify's free plan includes $5 of credit every month, which covers about 2,400 businesses at this actor's Free plan price with emails off ($0.002 a business plus $0.005 a run), or about 190 businesses with emails on at the rate of our proof run, about 150 of them with an email.

#### Copy to your AI assistant

```text
themineworks/panoramafirm-business-email-scraper on Apify. Searches PanoramaFirm.pl, the Polish business directory, by Polish trade word and place and returns one row per business with name, phones, address, postcode, coordinates, Warsaw district, website, rating and review count, plus an optional email (usually published on PanoramaFirm itself) and, with business pages on, the NIP tax number. Call ApifyClient("TOKEN").actor("themineworks/panoramafirm-business-email-scraper").call(run_input={"queries": ["hydraulik"], "locations": ["Warszawa"], "maxResultsPerSearch": 50, "includeEmails": true}), then client.dataset(run["defaultDatasetId"]).list_items().items. Required: queries (Polish trade words such as "hydraulik") unless startUrls is given. Optional: locations (city, county, voivodeship or Warsaw district; empty = all of Poland), startUrls (panoramafirm.pl search pages), maxResultsPerSearch (integer 1 to 1000, default 30), includeEmails (default false), includeDetails (default false), sortBy (popularity, rating, az or za; default popularity), openNow (default false), verifyEmailDomain (default true), allowUnblockerFallback (default true). Rows with _type "info" are run notes, never billed. Full spec: GET https://api.apify.com/v2/acts/themineworks~panoramafirm-business-email-scraper/builds/default (Bearer TOKEN), which returns inputSchema and readme. Token: https://console.apify.com/account/integrations
```

### Key features

- **Up to 1,000 businesses per search, up to 300 searches per run.** PanoramaFirm shows 25 businesses a page and serves up to 200 pages (5,000 businesses) for one search; the actor reads up to 1,000 of them per search, and the run summary repeats the count the site reports (998 dentists in Kraków and 114 plumbers in Warsaw in our runs). Each run takes up to 50 queries times 50 locations, capped at 300 searches.
- **28 fields per business**: listing id and PanoramaFirm link, name, category, every phone, the address split into street, postcode and town, coordinates, Warsaw district, distance from the searched place when the site shows one, website, rating and review count, description and NIP from the business page, the email and where it was found, and the search that found the row.
- **Contact data from the results page itself.** PanoramaFirm keeps phone, website and email in each result card, so a run without business pages makes one request per 25 businesses.
- **Emails from two places.** First the address the business published on PanoramaFirm, then its own website: homepage, then the Kontakt and legal pages it links to, then `/kontakt`, `/o-nas`, `/o-firmie` and `/polityka-prywatnosci`, at most 5 pages and 20 seconds per site. Website addresses are kept only on the business's own domain or an ordinary provider such as gmail.com, wp.pl, o2.pl, interia.pl or onet.pl. Every address, PanoramaFirm's own included, goes through a mail server check. Up to 5 addresses per row, best first.
- **The site's own sort and filter.** `sortBy` takes the site's orders (most popular, highest rated, A to Z, Z to A), and `openNow` keeps only businesses the site marks as open at the moment of the run.
- **Plain HTTP at 512 MB**, no browser. Every run writes a summary to the `OUTPUT` record in its key-value store: for each search the status (`ok`, `no_results` or `blocked`), the count the site reports, pages read and refused, connection attempts, and where the emails came from.

### How to use it

#### Basic: one trade in one city

```json
{
  "queries": ["hydraulik"],
  "locations": ["Warszawa"],
  "maxResultsPerSearch": 114
}
```

PanoramaFirm reported 114 plumbers for Warsaw on 28 Sep 2026, so this reads all 5 pages. The word must be Polish: the English `plumber` found 2 businesses in Warsaw.

#### Several trades in several cities

Every query runs in every location, so this is six searches:

```json
{
  "queries": ["elektryk", "hydraulik", "dekarz"],
  "locations": ["Wrocław", "Poznań"],
  "maxResultsPerSearch": 200
}
```

A business found by two of the searches under the same PanoramaFirm id is delivered once and charged once. Two searches run at a time.

#### Best rated businesses first

When you only need a short list, sort by rating so businesses with reviews come first:

```json
{
  "queries": ["fryzjer"],
  "locations": ["Gdańsk"],
  "maxResultsPerSearch": 25,
  "sortBy": "rating"
}
```

`sortBy` changes which businesses land on the first pages, so with a small `maxResultsPerSearch` it changes which ones you get.

#### NIP numbers and emails for a B2B list

```json
{
  "queries": ["dentysta"],
  "locations": ["Kraków"],
  "maxResultsPerSearch": 25,
  "includeEmails": true,
  "includeDetails": true
}
```

This is the input of our 1 Oct 2026 run: 25 businesses with 25 business pages in 17 seconds, every row with its NIP (`tax_id`), 19 with an email (17 from PanoramaFirm, 2 from the business's website) and 13 with a longer description. Business pages cost nothing extra.

#### Monthly refresh on a schedule

Save any of the inputs above as a task, then in Apify Console open Schedules, add a schedule (for example the first of every month) and pick the task. Each scheduled run is billed like a manual one, and the schedule itself is free. The actor has no "only new businesses" mode, so compare `listing_id` with your last export to find the newcomers.

#### Read a search you already set up on the site

```json
{
  "startUrls": [
    { "url": "https://panoramafirm.pl/szukaj?what=hydraulik&where=Warszawa" }
  ],
  "maxResultsPerSearch": 50
}
```

Each pasted page is read from its first page on, with the same limits and charges as a typed search. Business pages (whose address ends in `.html` after the place) are not read as searches.

### Input parameters

| Parameter | Type | Default | What it does |
|---|---|---|---|
| `queries` | array of strings | none (prefilled with `hydraulik`) | Polish trade words to search, one per line. Up to 50. Needed unless you give `startUrls`. |
| `locations` | array of strings | empty (prefilled with `Warszawa`) | Cities, counties, voivodeships or Warsaw districts, one per line. Every query is searched in every location. Empty searches all of Poland. Up to 50. |
| `startUrls` | array | empty | PanoramaFirm search result pages, read instead of or as well as the queries. |
| `maxResultsPerSearch` | integer | `30` | Most businesses per query and location, 1 to 1,000. The site shows 25 per page. |
| `includeEmails` | boolean | `false` | Add each business's email: the address published on PanoramaFirm first, then its website. Charged only for rows that come back with one. |
| `includeDetails` | boolean | `false` | Also open each business's own PanoramaFirm page, for the NIP tax number and, where the business wrote one, a longer description. No extra charge, slower. |
| `sortBy` | string | `popularity` | `popularity` (the site's default), `rating` (highest rated first), `az` or `za` (alphabetical). |
| `openNow` | boolean | `false` | Keep only businesses the site marks as open at the time of the run. Drastic: hydraulik in Warszawa went from 114 to 1 in our test, and businesses without published hours are left out. |
| `verifyEmailDomain` | boolean | `true` | Keep an email only when its domain can receive mail. Applies to PanoramaFirm's and website emails alike. |
| `allowUnblockerFallback` | boolean | `true` | When a search page is refused several times over the fast connection, retry it through Apify's unblocking proxy. Included in the price. Turn off to report such pages as refused instead. |

Give at least one query or one search page. A run with neither writes a note row and stops; the $0.005 start fee still applies.

### What data do you get?

One row per business. Fields with no value are left out of the row rather than sent as empty.

**The business**

- `listing_id` (PanoramaFirm's id, such as `company_11792529_3660`), `listing_url`, `name`, `categories` (the category on the card, such as `Hydraulicy`), `rating` (when the business has reviews) and `review_count` (`0` when it has none), `description` (from the business page, when the business wrote one)

**Contact**

- `phone` (the first number) and `phones` (all of them), in international format such as `+48 519 381 179`; `website`, with `utm_`, `fbclid`, `gclid` and `mc_` tracking parameters removed

**Address and map**

- `address` (one line), `street`, `postal_code` (such as `02-486`), `city`, `country` (always `PL`), `latitude`, `longitude`, `district` (the Warsaw borough, for addresses in Warsaw only) and `distance_km` (only when the card shows a distance from the place you searched)

**Tax number** (with `includeDetails` on)

- `tax_id`, the Polish NIP, such as `6772202623`

**Email** (with `includeEmails` on)

- `email` (the best address), `emails` (up to 5, best first), `email_source` (`directory` or `website`) and `email_source_url` (the PanoramaFirm page, or the website page it was read from)

**Search context**

- `source_site` (`panoramafirm.pl`), `search_query`, `search_location`, `scraped_at`

A few things to know about the fields:

- **A small town is filled with businesses from farther away.** When a place has few matches, PanoramaFirm adds the nearest businesses of neighbouring towns and counts them in its total; those cards carry `distance_km` and their own `city`. A paid top card can show a distance too: the first row of our Warsaw proof run was a business in Kobyłka, 19 km away.
- **A village address has no street.** Addresses like `05-500 Mysiadło 10E` are split into postcode and town only.
- **One business can have two PanoramaFirm ids**, for a second registration or a second trade. The actor merges the two when they appear on the same page; in separate searches both ids can come back.
- **Opening hours** come only from the business page, and none of the 25 Kraków business pages in our 1 Oct 2026 run had any.
- **Ratings are the average and the count only**, not the review texts, and only for businesses with at least one review.

Fill rates in the proof run (20 businesses, emails on): phone 20, email 16, coordinates 18, district 17, website 9, rating 6.

#### Stable fields for automations

These fields were present in every one of 84 business rows across the proof run, our 1 Oct 2026 Kraków run and the result cards saved for our tests (including a small town search filled from farther away), and their names will not change:

| Field | What it holds |
|---|---|
| `listing_id` | PanoramaFirm's id for the business listing |
| `listing_url` | Link to the business's page on panoramafirm.pl |
| `name` | Business name as listed |
| `categories` | The category on the card, as a list |
| `address` | The address on one line, as the card shows it |
| `postal_code` | Polish postcode, such as `02-486` |
| `city` | Town as the card gives it, sometimes with the city district attached (`Kraków Bronowice`); in Warsaw the borough goes to `district` |
| `country` | Always `PL` |
| `review_count` | Number of reviews, `0` when there are none |
| `source_site` | Always `panoramafirm.pl` |
| `search_query` | The query or pasted search that found the row |
| `scraped_at` | When the row was read (ISO 8601) |

`search_location` is present whenever the search had a place. `phone` was missing on 5 of the 25 Kraków rows and `street` on village addresses, so test for them before you rely on them.

#### Output examples

Real rows, trimmed where marked. From the proof run on 28 Sep 2026 (`hydraulik` in `Warszawa`, emails on), a company with its email on PanoramaFirm and its Warsaw borough (complete row):

```json
{
  "listing_id": "company_11792529_3660",
  "listing_url": "https://panoramafirm.pl/mazowieckie,,warszawa,w%C5%82ochy,al._jerozolimskie,214/aries_sp._z_o.o.-alnabi_fhm.html",
  "name": "Aries Sp. z o.o.",
  "categories": ["Hydraulicy"],
  "phone": "+48 519 381 179",
  "phones": ["+48 519 381 179"],
  "address": "Al. Jerozolimskie 214, 02-486 Warszawa Włochy",
  "street": "Al. Jerozolimskie 214",
  "postal_code": "02-486",
  "city": "Warszawa",
  "country": "PL",
  "latitude": 52.19027,
  "longitude": 20.91825,
  "email": "ariesspzoo@gmail.com",
  "emails": ["ariesspzoo@gmail.com"],
  "email_source": "directory",
  "email_source_url": "https://panoramafirm.pl/mazowieckie,,warszawa,w%C5%82ochy,al._jerozolimskie,214/aries_sp._z_o.o.-alnabi_fhm.html",
  "review_count": 0,
  "district": "Włochy",
  "source_site": "panoramafirm.pl",
  "search_query": "hydraulik",
  "search_location": "Warszawa",
  "scraped_at": "2026-09-28T12:46:42.907Z"
}
```

From the same run, a company with 55 reviews but no email and no website on PanoramaFirm, charged as a business only (trimmed):

```json
{
  "listing_id": "company_16228795_3660",
  "name": "Al-Mat Sp. z o.o.",
  "categories": ["Hydraulicy"],
  "phone": "+48 606 840 400",
  "address": "ul. Spedycyjna 24 lok. 1.28, 03-191 Warszawa",
  "postal_code": "03-191",
  "city": "Warszawa",
  "rating": 3.4,
  "review_count": 55
}
```

From our 1 Oct 2026 run with business pages on (`dentysta` in `Kraków`), a clinic with its NIP, description, rating and email (complete row):

```json
{
  "listing_id": "company_121972343_370",
  "listing_url": "https://panoramafirm.pl/ma%C5%82opolskie,,krak%C3%B3w,bronowice,krakus%C3%B3w,1c/stomatologia_steczko_sp._z_o.o.-sgsrmy_sj.html",
  "name": "Stomatologia Steczko Sp. z o.o.",
  "categories": ["Stomatolodzy i protetycy"],
  "phone": "+48 601 397 681",
  "phones": ["+48 601 397 681"],
  "address": "ul. Krakusów 1c, 30-092 Kraków Bronowice",
  "street": "ul. Krakusów 1c",
  "postal_code": "30-092",
  "city": "Kraków Bronowice",
  "country": "PL",
  "website": "https://www.steczkodentysta.pl",
  "email": "biuro@steczkodentysta.pl",
  "emails": ["biuro@steczkodentysta.pl"],
  "email_source": "directory",
  "email_source_url": "https://panoramafirm.pl/ma%C5%82opolskie,,krak%C3%B3w,bronowice,krakus%C3%B3w,1c/stomatologia_steczko_sp._z_o.o.-sgsrmy_sj.html",
  "rating": 5,
  "review_count": 102,
  "description": "Klinika stomatologiczna Steczko znajduje się w Krakowie. Swoje usługi świadczymy już od 1999 roku. Właścicielami są Anna i Wacław Steczko.",
  "tax_id": "6772202623",
  "source_site": "panoramafirm.pl",
  "search_query": "dentysta",
  "search_location": "Kraków",
  "scraped_at": "2026-10-01T13:54:56.332Z"
}
```

The note row at the end of the run (never charged; filter on `_type` to drop it), trimmed:

```json
{
  "_type": "info",
  "delivered": 20,
  "message": "20 businesses delivered. This row is informational: it is never billed.",
  "scraped_at": "2026-09-28T12:46:46.280Z"
}
```

### Pricing

You pay per business delivered to your dataset, plus a flat start fee per run. An email is a second, separate charge, made only for rows that come back with one. The fast connection and the unblocking proxy fallback are included.

| Event | Free plan | Starter (Bronze) | Scale (Silver) | Business (Gold) and above |
|---|---|---|---|---|
| Business delivered (`listing-scraped`), per business | $0.002 | $0.0017 | $0.0014 | $0.001 |
| Business delivered, per 1,000 | $2.00 | $1.70 | $1.40 | $1.00 |
| Email found (`email-found`), per email | $0.03 | $0.025 | $0.02 | $0.015 |
| Email found, per 1,000 | $30 | $25 | $20 | $15 |
| Run start (`run-start`), once per run | $0.005 | $0.005 | $0.005 | $0.005 |

The start fee is our own `run-start` event: a flat $0.005 once per run, whatever memory you choose. It is not Apify's per GB start fee, and it is charged on every run, including a run that finds nothing. These prices took effect on 28 Sep 2026, and no change is scheduled as of 1 Oct 2026. The Pricing tab always shows the rate for your own plan; if this table and the Pricing tab ever disagree, the Pricing tab is right.

**What a real job costs.** 1,000 businesses with emails off cost $2.00 plus $0.005 on the Free plan, and $1.00 plus $0.005 on Business. With emails on, at the rates of our two runs (16 of 20 and 19 of 25), 1,000 businesses bring about 780 emails: about $23.40 more on Free and $11.70 more on Business. Turn emails on only for the searches where you need them; business pages cost nothing extra.

Never charged:

- search pages the site refused, and the retries through the unblocking proxy;
- a business already delivered by another search in the same run, under the same PanoramaFirm id;
- a search for a place PanoramaFirm does not know, which it would have widened to all of Poland (nothing is delivered);
- business pages and websites that were opened but gave no email (the row is charged as a business only);
- an email address already charged earlier in the same run, such as the shared inbox of a chain's branches (it is still delivered on every row);
- the note row and the `OUTPUT` run summary.

To cap what a run can cost, set a maximum total charge in the run options. The actor stops before a business the budget cannot pay for, and when the budget covers a business but not its email, the row is delivered without the email and the email is not charged.

### FAQ

#### What is PanoramaFirm.pl?

One of Poland's largest business directories, run by WeNet. It lists tradespeople, shops, clinics, restaurants, professionals and companies across Poland, with phone, address, website and, for most listings, an email.

#### How many businesses can I get?

Up to 1,000 per search and up to 300 searches per run. The site itself serves at most 200 pages (5,000 businesses) for one search, so a nationwide trade such as `restauracja` (22,743 results on 28 Sep 2026) can never be read in full from one search: split it by city or voivodeship. A run stops cleanly before its timeout (one hour by default) and keeps everything delivered so far, so raise the timeout in the run options for very large runs.

#### What do I type into Queries?

The Polish trade word as you would type it on PanoramaFirm.pl: `hydraulik`, `elektryk`, `dentysta`, `fryzjer`, `restauracja`, `prawnik`. English words find almost nothing (`plumber` found 2 businesses in Warsaw against 114 for `hydraulik`). Close variants are different words to the site: `hydraulika` is narrower than `hydraulik`.

#### What do I type into Locations?

A city (`Kraków`, `Wrocław`), a county, a voivodeship (`mazowieckie`, `małopolskie`) or a Warsaw district on its own (`Mokotów`). Diacritics are optional. Postcodes are not recognised: a place the site does not know is dropped by the site, which then searches all of Poland, so the actor stops that search and says so in the run summary instead of delivering nationwide rows.

#### Why are some businesses outside the place I searched?

For a small town with few matches, PanoramaFirm itself adds the nearest businesses from neighbouring towns and counts them in its total. Those rows carry `distance_km` and their own `city`, so filter on them if you need the exact town only. A very small or rural place can return only distant businesses.

#### How fresh is the data?

Every run reads the site live; nothing comes from a cache. `scraped_at` on each row says when it was read.

#### Do I need a PanoramaFirm account, cookies or an API key?

No. The actor reads the public pages any visitor sees, without signing in. There is nothing of yours to connect.

#### Do I need to set up a proxy?

No. The actor uses a fast connection that looks like a normal Chrome browser, through Apify's datacenter proxies, and PanoramaFirm answered every search and business page that way in our 1 Oct 2026 runs. A refused search page is retried through Apify's unblocking proxy, included in the price; refused pages are listed in the run summary and never charged.

#### Will every business have an email?

No, but most do: 16 of 20 in the Warsaw proof run and 19 of 25 in the Kraków run, nearly all published on PanoramaFirm itself. For a card without an email, the actor tries the business's own website. A business with neither an email on PanoramaFirm nor a website gives none. The actor never guesses an address from a name, and you pay nothing extra for a row without one.

#### Which pages does it read?

Search pages (`/szukaj?what=...&where=...` or the site's short form) and, with `includeDetails` on, business pages. PanoramaFirm's robots.txt, read again on 1 Oct 2026, is `Allow: /` for every crawler.

#### Can I get only the new businesses each month?

There is no "only new" mode in this actor. Schedule the same input and compare `listing_id` with your last export.

#### Which formats can I export?

JSON, CSV, Excel, XML, HTML table and RSS from the dataset page in Apify Console, or through the Apify API.

#### Can I use it from Claude, ChatGPT or another AI agent?

- Connector URL: `https://mcp.apify.com/?tools=themineworks/panoramafirm-business-email-scraper`.
- Claude: Settings > Connectors > Add custom connector, paste the URL, sign in with Apify.
- ChatGPT: developer mode, add an MCP connector with the URL, sign in with Apify.
- Cursor or VS Code: add it as an HTTP MCP server with that URL.
- Claude Code: `claude mcp add -t http panoramafirm-business-email-scraper "https://mcp.apify.com/?tools=themineworks/panoramafirm-business-email-scraper"`.

#### Is it legal to scrape PanoramaFirm.pl?

The actor collects only publicly visible business listings and never signs in. Business contact details are still personal data when they identify a person, and many Polish listings are sole traders under their own name, so how you store and use them is your responsibility: follow the site's terms and the GDPR (RODO), and where you send marketing messages also Poland's electronic communications rules, which require prior consent for commercial email (and CAN-SPAM or the CCPA for contacts in the US). This is general information, not legal advice. The actor is an independent tool, not affiliated with or endorsed by PanoramaFirm or WeNet.

### Integrations

- **Google Sheets**: send each run's dataset to a sheet with Apify's Google Sheets integration.
- **Make, Zapier and n8n**: start runs and receive the businesses in your workflows.
- **Webhooks**: get a call when a run finishes, for example to load new rows into your CRM.
- **API**: start runs and read datasets from any language with the Apify API or the Python and JavaScript clients.
- **MCP clients**: Claude, ChatGPT and other agents through Apify's MCP server.

### More from The Mine Works

**Leads and business directories**

- [B2B Leads Finder](https://apify.com/themineworks/b2b-leads-finder)
- [Skip Trace Lookup](https://apify.com/themineworks/skip-trace-lookup)
- [Google Maps Email Scraper](https://apify.com/themineworks/maps-leads)
- [JustDial Scraper](https://apify.com/themineworks/justdial-business)
- [2GIS Places Scraper](https://apify.com/themineworks/2gis-places-search)
- [IndiaMART Scraper](https://apify.com/themineworks/indiamart-suppliers)
- [Yandex Maps Scraper](https://apify.com/themineworks/yandex-maps-search)
- [Contact Details Scraper](https://apify.com/themineworks/website-contact-finder)
- [US Business Registry](https://apify.com/themineworks/us-state-business-registry)
- [Google Maps Scraper](https://apify.com/themineworks/google-maps-search-scraper)
- [Yellow Pages Scraper](https://apify.com/themineworks/yellowpages-us)
- [Lead Generation MCP](https://apify.com/themineworks/lead-generation-mcp)

**Social media and video**

- [Threads Scraper](https://apify.com/themineworks/threads-scraper)
- [Reddit Scraper](https://apify.com/themineworks/reddit-scraper)
- [Threads Search Scraper](https://apify.com/themineworks/threads-search-scraper)
- [Instagram Profile Scraper](https://apify.com/themineworks/instagram-profile-scraper)

**Marketing, SEO and reviews**

- [Facebook Ad Library Scraper](https://apify.com/themineworks/meta-ad-library-scraper)
- [Similarweb Scraper](https://apify.com/themineworks/similarweb-scraper)
- [Google Ads Transparency Scraper](https://apify.com/themineworks/google-ads-transparency)
- [Google News Scraper](https://apify.com/themineworks/google-news)

**LinkedIn**

- [LinkedIn Company Scraper](https://apify.com/themineworks/linkedin-company-details)
- [LinkedIn Post Scraper](https://apify.com/themineworks/linkedin-post-search)
- [LinkedIn Employees Scraper](https://apify.com/themineworks/linkedin-employees)
- [LinkedIn Profile Scraper](https://apify.com/themineworks/linkedin-profile-scraper)

**Real estate**

- [Zillow Rentals Scraper](https://apify.com/themineworks/zillow-rental-listings)
- [Zillow Sold Comps Scraper](https://apify.com/themineworks/zillow-recently-sold)
- [Housing.com Scraper](https://apify.com/themineworks/housing-com-scraper)
- [India Real Estate MCP](https://apify.com/themineworks/india-real-estate-mcp)

**Science, health and government data**

- [CourtListener Scraper](https://apify.com/themineworks/courtlistener-court-records)
- [data.gov.in Scraper](https://apify.com/themineworks/india-data-gov-scraper)
- [Socrata Open Data Scraper](https://apify.com/themineworks/socrata-open-data)
- [Academic Research MCP](https://apify.com/themineworks/academic-research-mcp)

**Jobs and hiring**

- [Foundit Monster India Jobs](https://apify.com/themineworks/foundit-jobs-scraper)
- [Hirist Jobs Scraper](https://apify.com/themineworks/hirist-jobs-scraper)
- [India Jobs MCP](https://apify.com/themineworks/india-jobs-mcp)
- [Naukri Jobs Scraper](https://apify.com/themineworks/naukri-jobs)

**E-commerce and marketplaces**

- [Ozon.ru Scraper](https://apify.com/themineworks/ozon-product-search)
- [⭐ Amazon Reviews Scraper](https://apify.com/themineworks/amazon-reviews)
- [Amazon Product Scraper](https://apify.com/themineworks/amazon-products)
- [Carsales.com.au Scraper](https://apify.com/themineworks/carsales-scraper)

**Company and business data**

- [Company Domain Finder](https://apify.com/themineworks/company-domain-finder)
- [GST Taxpayer Lookup](https://apify.com/themineworks/gst-taxpayer-lookup)
- [World Bank Trade Scraper](https://apify.com/themineworks/global-trade-data)
- [Company KYB Resolver](https://apify.com/themineworks/company-identity-resolver)

**Food and local services**

- [NoBroker Scraper](https://apify.com/themineworks/nobroker-scraper)
- [Swiggy Restaurant Scraper](https://apify.com/themineworks/swiggy-scraper)
- [Zomato Scraper](https://apify.com/themineworks/zomato-scraper)

**Developer and AI tools**

- [Website to Markdown Crawler](https://apify.com/themineworks/rag-crawler)
- [GitHub Skill Finder](https://apify.com/themineworks/github-skill-discovery)
- [GitHub Repo Scraper](https://apify.com/themineworks/github-repo-intelligence)
- [GitHub Trending Scraper](https://apify.com/themineworks/github-trending-scraper)

**More tools**

- [Tennis Match & Player Data Scraper](https://apify.com/themineworks/tennis-match-data)
- [Google Hotels Prices Scraper](https://apify.com/themineworks/google-hotels-prices-scraper)
- [LandWatch Scraper](https://apify.com/themineworks/landwatch-land-for-sale-scraper)

### Support

Found a problem or need a field? Open an issue on the actor's Issues tab and we will answer there. For a new source or a custom build, email dmineworks@gmail.com.

*PanoramaFirm Scraper turns a Polish trade word and a place into rows of businesses with phone, address, coordinates and, when you want them, the email PanoramaFirm publishes and the company's NIP.*

# Actor input Schema

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

Business types or trades to search, one per line, for example hydraulik. Each query is searched in every location below. Needed unless you paste search pages into Start URLs. Up to 50 per run.

## `locations` (type: `array`):

Town, city, region or postcode, one per line, typed the way you would on panoramafirm.pl, for example Warszawa. Leave empty to search the whole country. Up to 50 per run.

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

Optional. Paste search result pages from panoramafirm.pl instead of, or as well as, Queries and Locations. Each page is read from its first page on.

## `maxResultsPerSearch` (type: `integer`):

Most businesses to return for each query and location, 1 to 1,000. The directory shows 25 per page, so 100 businesses take about 4 pages. PanoramaFirm.pl serves at most 200 pages (5000 businesses) for one search.

## `includeEmails` (type: `boolean`):

Off by default. Turn on to look for each business's email address: first the address the directory publishes, then the business's own website (homepage, then its contact and legal pages). You are charged the email price only for rows that come back with an email; a business where none is found costs nothing extra.

## `includeDetails` (type: `boolean`):

Also open each business's own page on the directory for the extra fields it holds, such as coordinates, opening hours, categories and registration numbers. Slower, and no extra charge. With Find emails on, the business page is opened anyway when the search result has no email.

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

Order of the results, the same choices the site offers. Highest rated puts businesses with reviews first, which helps when you only need a few.

## `openNow` (type: `boolean`):

Only businesses the site marks as open right now. Drastic on this site (hydraulik in Warszawa goes from 114 to 1); the answer depends on the day and hour of the run, and businesses without published hours are left out.

## `verifyEmailDomain` (type: `boolean`):

Only keep an email when its domain can receive mail (it has a mail server). Removes addresses of dead or misspelled domains, so you are not charged for them. Only used when Find emails is on.

## `allowUnblockerFallback` (type: `boolean`):

Search pages are read over a fast connection first. If the site refuses a page several times, try it through Apify's unblocking proxy, which is slower. Included in the price. Turn off to report such pages as refused instead.

## Actor input object example

```json
{
  "queries": [
    "hydraulik"
  ],
  "locations": [
    "Warszawa"
  ],
  "maxResultsPerSearch": 30,
  "includeEmails": false,
  "includeDetails": false,
  "sortBy": "popularity",
  "openNow": false,
  "verifyEmailDomain": true,
  "allowUnblockerFallback": true
}
```

# 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 = {
    "queries": [
        "hydraulik"
    ],
    "locations": [
        "Warszawa"
    ],
    "maxResultsPerSearch": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("themineworks/panoramafirm-business-email-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "queries": ["hydraulik"],
    "locations": ["Warszawa"],
    "maxResultsPerSearch": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("themineworks/panoramafirm-business-email-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "hydraulik"
  ],
  "locations": [
    "Warszawa"
  ],
  "maxResultsPerSearch": 30
}' |
apify call themineworks/panoramafirm-business-email-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,themineworks/panoramafirm-business-email-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/EnLrE5ClJuGz3NHj1/builds/2Xv0aCs2RpoQ2JAvH/openapi.json
