# Poland Local Statistics – GUS BDL API (Gmina, Powiat, TERYT) (`almmity/gus-bdl-poland-local-statistics`) Actor

Official GUS Bank Danych Lokalnych (BDL) API as flat rows for gmina, powiat and voivodeship: population, REGON, unemployment, budgets, housing. Includes TERYT codes. No scraping.

- **URL**: https://apify.com/almmity/gus-bdl-poland-local-statistics.md
- **Developed by:** [Almmity](https://apify.com/almmity) (community)
- **Categories:** Business, AI
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.50 / 1,000 statistics row returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## GUS BDL API Scraper – Bank Danych Lokalnych, TERYT, Polish Local Statistics

Official **Statistics Poland (GUS)** data for every **gmina, powiat and województwo** as one flat table: population, REGON firms, wages, unemployment, housing, municipal budgets and tens of thousands of other **Bank Danych Lokalnych (BDL)** variables. Includes official **TERYT** codes for GIS/CRM joins. Export to Excel, CSV, JSON, Google Sheets, Power BI or your own app via the Apify API.

**PL:** Oficjalne dane **GUS / Bank Danych Lokalnych** dla gmin, powiatów i województw w jednej tabeli, z kodami **TERYT**. Bez ręcznego szukania ID jednostek i bez stronicowania API. Wpisz słowo (np. „bezrobocia”, „REGON”, „mieszkania oddane”), wybierz poziom i lata – pobierz Excel lub CSV.

Source: public GUS BDL REST API (`bdl.stat.gov.pl/api/v1`). No scraping, no login.

### Who is this for

- **Real-estate / retail location analysts** – population, dwellings, wages by gmina or powiat for site selection.
- **Franchise & expansion teams** – REGON firm density and unemployment maps before opening a new city.
- **Grant / EU-funds consultants** – regional indicators for applications (pairs with [Poland EU Funding Calls (Nabory)](https://apify.com/almmity/poland-eu-funding-calls)).
- **Local journalists, students, market researchers** – reproducible GUS extracts without clicking through bdl.stat.gov.pl.

### Why use it

- **Official source only** – GUS BDL API, not HTML scraping.
- **Flat rows** – one row = unit × indicator × year, with readable names, measure unit, BDL unit ID and **TERYT**.
- **Find variables by word** – type Polish search terms; matched variable IDs are logged.
- **Any level down to gmina**, optionally limited to one voivodeship or powiat (`parentUnitId`).
- **Handles GUS rate limits** (waits/retries on HTTP 429). Optional free BDL `clientId` for very large pulls.

### Input examples by buyer type

Location analyst – population of every voivodeship, 2023–2024:

```json
{"presets": ["population"], "unitLevel": "2", "years": ["2023", "2024"]}
```

Franchise expansion – firms per 10k residents in every gmina of Mazowieckie, 2024:

```json
{"searchTerms": ["REGON na 10 tys"], "maxVariablesPerSearch": 1, "unitLevel": "6", "parentUnitId": "071400000000", "years": ["2024"]}
```

Grant consultant – unemployment + budget revenue + dwellings for every powiat, 2023–2024:

```json
{"presets": ["unemployment_rate", "budget_own_revenue_pc", "dwellings_per_1000"], "unitLevel": "5", "years": ["2023", "2024"], "maxItems": 5000}
```

Ready-made presets: `population`, `firms_per_10k`, `wage_vs_national` (relative PL=100; BDL has no absolute PLN average wage at powiat/gmina), `unemployment_rate` (December registered rate), `dwellings_per_1000`, `budget_own_revenue_pc` (gmina budgets), `powiat_budget_own_revenue_pc` (powiat budgets, 314 land powiats with real values, 2002–2025; the 66 cities with powiat rights return 0 here because GUS books their revenue in the city/gmina budget, so use `budget_own_revenue_pc` for them; 2024 median for land powiats: 714.80 zł).

### Output example

```json
{"variableId": 72305, "variableFullName": "Ludność wg grup wieku i płci: ogółem – ogółem", "measureUnit": "osoba",
 "unitId": "071412865028", "unitName": "Bemowo - dzielnica", "teryt": "1465028", "unitLevel": 6, "unitLevelName": "gmina",
 "year": 2024, "value": 128895, "attrId": 1}
```

Fields: `variableId`, `variableName`, `variableFullName`, `subjectId`, `subjectName`, `measureUnit`, `unitId`, `unitName`, `teryt` (official TERYT: 2 digits voivodeship, 4 powiat, 7 gmina incl. type digit – join with GUS TERYT, PRG/GIS maps; empty for NUTS 0/1/3/4), `unitLevel`, `unitLevelName`, `parentUnitId`, `year`, `value`, `attrId`, `apiUrl`.

### Example dataset (demo run)

Cheap public demo on build **0.1.10** (2026-10-16): `presets: ["population"]`, `unitLevel: "2"`, `years: ["2024"]` → **16 voivodeship rows** with TERYT.

- [Open demo run](https://console.apify.com/view/runs/U2zaeewbzuDkYTWvD)
- [Open dataset](https://console.apify.com/storage/datasets/LTf2WBZhaD2N9JNJN)
  Or click **Try for free** on the Store page with the default example input.

### Unit levels

0 Poland, 1 macroregion, 2 voivodeship (województwo), 3 region, 4 subregion (podregion), 5 powiat, 6 gmina. Variables not published at the chosen level are skipped with a log warning. Level 6 returns about 4,200 units (urban/rural parts of mixed gminas and Warsaw districts listed separately).

### Pricing

Pay per result: you pay only for rows returned. Use `maxItems` and `years` to control cost.

### Related actors (same publisher)

- [Poland EU Funding Calls (Nabory) – Dotacje UE i KPO](https://apify.com/almmity/poland-eu-funding-calls) – official MFiPR nabory / fundusze europejskie tables.
- [App Store Reviews Scraper – official Apple RSS feed](https://apify.com/almmity/app-store-reviews-official-feed) – iOS reviews via Apple’s public customer-review feed.

### Tips

- Leave `years` empty for the whole time series (often 1995–2025).
- Common voivodeship IDs: 071400000000 Mazowieckie, 011200000000 Małopolskie, 012400000000 Śląskie. Run once at level 2 to see all 16.
- Data licence: GUS publishes BDL for free reuse; cite "Źródło: GUS, Bank Danych Lokalnych".

Keywords: GUS BDL, Bank Danych Lokalnych, GUS API, BDL API, TERYT, dane GUS gminy, statystyka powiatów, Polish local statistics, ludność gmin, bezrobocie powiaty, REGON, dochody własne gmin.

# Actor input Schema

## `presets` (type: `array`):

Quick start without looking up variable IDs.

## `searchTerms` (type: `array`):

Polish words work best (the BDL catalogue is in Polish), e.g. 'bezrobocia', 'REGON na 10 tys', 'mieszkania oddane', 'wynagrodzenia brutto'. Each term adds up to 'Max variables per search'. Matched variables are listed in the run log.

## `maxVariablesPerSearch` (type: `integer`):

How many matching variables each search term may add (most relevant first).

## `variableIds` (type: `array`):

Exact BDL variable IDs, e.g. 72305 (population total). Find them at bdl.stat.gov.pl or with 'Search variables'.

## `unitLevel` (type: `string`):

Variables not published at this level are skipped with a warning.

## `parentUnitId` (type: `string`):

Optional 12-digit BDL unit ID, e.g. 071400000000 = Mazowieckie. With level 6 this returns only gminas of that voivodeship.

## `years` (type: `array`):

e.g. 2023, 2024. Empty = every year available (can be many rows).

## `lang` (type: `string`):

Language of subject and variable names where GUS provides translations.

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

0 = no limit.

## `clientId` (type: `string`):

Free key from https://api.stat.gov.pl/Home/BdlApi raises GUS rate limits for big pulls (all ~4,200 gmina-level units, many years). Not needed for normal runs.

## Actor input object example

```json
{
  "presets": [
    "population"
  ],
  "searchTerms": [],
  "maxVariablesPerSearch": 10,
  "variableIds": [],
  "unitLevel": "2",
  "parentUnitId": "",
  "years": [
    "2024"
  ],
  "lang": "pl",
  "maxItems": 10000
}
```

# Actor output Schema

## `results` (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 = {
    "presets": [
        "population"
    ],
    "years": [
        "2024"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("almmity/gus-bdl-poland-local-statistics").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 = {
    "presets": ["population"],
    "years": ["2024"],
}

# Run the Actor and wait for it to finish
run = client.actor("almmity/gus-bdl-poland-local-statistics").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 '{
  "presets": [
    "population"
  ],
  "years": [
    "2024"
  ]
}' |
apify call almmity/gus-bdl-poland-local-statistics --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,almmity/gus-bdl-poland-local-statistics"
        }
    }
}
```

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/RATDRrQWag7trTk4f/builds/Y2oMZgm0KxBupVhxw/openapi.json
