Parcel data and exports (DXF, GeoJSON, SHP, PDF map sheet) for construction firms, design offices, real-estate agencies and CRM integrations. Public GUGiK data only.
Create a key in My plan → API keys (Pro plan). Send it in a header:
X-API-Key: pk_live_… or Authorization: Bearer pk_live_…
The key is shown once; we only store its SHA-256 hash. You can revoke it at any time.
| Parameter | Description |
|---|---|
id | TERYT parcel ID, e.g. 141804_4.0006.9/5 |
address | or an address: street number, city (GUGiK geocoder → parcel under the address point) |
curl -H "X-API-Key: $PARCEL_KEY" "https://parcel-staging.imetroll.com/api/v1/parcel?id=141804_4.0006.9/5"
{ "parcel": { "parcel_id": "141804_4.0006.9/5", "parcel_no": "9/5", "region": "06", "commune": "Piaseczno", "area_m2": 2215.6, "vertices": 12, "pl2000_zone": 7, … },
"geometry": { "type": "Polygon", "crs": "EPSG:4326", "coordinates": [[…]] },
"mpzp": { "covered": true|false|null, "plans": [{ "nazwa": …, "uchwala": …, "tresc": "https://…" }], "zones": [{ "symbol": …, "opis": … }], "pog": […] },
"exports": [ "/api/v1/export?id=…&fmt=dxf&crs=2180", … ] }
mpzp contains only what KIMP / municipal general plans publish at the parcel centroid; null = service did not answer. The municipal resolution is binding.
| Parameter | Values |
|---|---|
id / address | as above |
fmt | dxf (R12; layers GRANICA, NUMER, WIERZCHOLKI, SASIEDZI, TABELA, OPIS) · geojson · shp (ZIP: .shp .shx .dbf .prj .cpg, boundary + vertices) · pdf / png (A4 sheet, auto scale 1:500/1:1000/1:2000) |
crs | 2180 (PL-1992) · 2000 (PL-2000, auto zone EPSG:2176–2179) · 4326 (only geojson) |
nb=1 | DXF: neighbouring parcel outlines |
lang, base | pdf/png: pl|en, orto|map |
curl -H "X-API-Key: $PARCEL_KEY" -o dzialka.dxf "https://parcel-staging.imetroll.com/api/v1/export?id=141804_4.0006.9/5&fmt=dxf&crs=2000&nb=1"
Offers = parcel reports ordered by your account or company (API key scope). Every response passes the central privacy filter.
| Call | Description |
|---|---|
GET /api/v1/offers?limit=&offset=&since= | list (summary) |
GET /api/v1/offers?id=10 | full JSON dataset: parcel, parameters, boundaries (WGS84, PL-1992, PL-2000), zoning MPZP/POG, map, photos, agency registry data |
&view=buyer | buyer view: parcel, boundaries, zoning, parameters, photos, map only |
&fmt=csv|xml|json, id=all | file (CSV: UTF-8 with BOM, separator ;) |
&connector=enova365|symfonia|asari|esticrm|galactica_virgo|otodom|olx|nieruchomosci_online|gratka_domy | file in CRM connector layout (mapping configurable per company) |
PATCH /api/v1/offers?id=10 | JSON {title, asking_price, currency, description, status: draft|active|reserved|sold|withdrawn, photos:[https://…]} → webhook offer.updated / offer.status_changed |
POST /api/v1/webhooks {"url":"https://crm.example.com/parcel","events":"offer.*"} | register; response contains the secret (shown once) |
GET /api/v1/webhooks · DELETE ?id= | list / disable |
POST ?id=&op=test · GET ?id=&op=deliveries · POST ?id=&op=redeliver&delivery= | test, delivery log, redeliver |
Events: offer.created, offer.updated, offer.status_changed, webhook.test. Signature: X-Parcel-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, t + "." + raw_body)>. Reply 2xx within 10 s; otherwise retries after 1 min, 5 min, 30 min, 2 h, 12 h (6 attempts), then status dead. URL must be public HTTPS (private addresses blocked).
| System | Status |
|---|---|
| Parcel CSV / XML / JSON | verified (own format) |
| EstiCRM | API exists (public docs, company + token); writing offers as a 3rd party needs the client's credentials and method confirmation. Today: JSON file for import. |
| ASARI CRM | API exists (api.asari.pro, userId + Token); partner write methods not verified – needs ASARI agreement. Today: JSON file (LotSale). |
| enova365, Symfonia | conceptual: CSV file to match the client's import template; no verified public offer API |
| Otodom, OLX, Gratka/Domy.pl, Nieruchomosci-online, Galactica Virgo | conceptual: portals take offers from the agency CRM (Otodom via WEB API after agency authorization). Parcel → CRM → portal. Direct push needs a partner agreement. |
POST /api/v1/connectors?connector=enova365 {"mapping":{"Kod":"offer_id","Nazwa":"offer_title","Cecha_MPZP":"mpzp_symbols"},"options":{"separator":";"}} – custom column mapping (company owner/admin).
***, no credit, mortgage or encumbrance data (land register sections III/IV), KW persons masked. Company registry data (NIP, REGON) is allowed; fictional test numbers used here.=IMPORTDATA() from your own proxy (never put the API key into a sheet). LibreOffice Calc: Open → charset UTF-8, separator ;.parcel.offer.v1) periodically or on webhook.offer_id;offer_status;offer_title;offer_asking_price;parcel_id;parcel_no;commune;area_m2;mpzp_covered;mpzp_symbols;boundary_wkt_wgs84;map_url;agency_nip;agency_regon;owner_name;kw_number;kw_persons 10;active;"Działka budowlana 2216 m² (PRZYKŁAD)";789000;141804_4.0006.9/5;9/5;Piaseczno;2215.6;TAK/YES;MN;"POLYGON((21.02314272 52.08505105,…))";https://parcel-staging.imetroll.com/app.php?center=21.023562,52.084863&z=18;1234563218;123456785;***;WA1M/********/*;***
# Python
import csv, requests
r = requests.get("https://parcel-staging.imetroll.com/api/v1/offers", params={"id": "all", "fmt": "csv"}, headers={"X-API-Key": KEY})
rows = list(csv.DictReader(r.content.decode("utf-8-sig").splitlines(), delimiter=";"))
print(rows[0]["parcel_id"], rows[0]["area_m2"], rows[0]["mpzp_symbols"])
<?php // PHP
$ctx = stream_context_create(['http' => ['header' => "X-API-Key: " . getenv('PARCEL_KEY')]]);
$o = json_decode(file_get_contents('https://parcel-staging.imetroll.com/api/v1/offers?id=10', false, $ctx), true);
echo $o['parcel']['parcel_id'], ' ', $o['parameters']['area_m2'], ' m², MPZP: ', $o['mpzp']['zones'][0]['symbol'] ?? '-';
offer.created / offer.updated reaches the agency system (or the agent clicks "Export to CRM")./api/v1/offers?id=…&connector=esticrm (or the CSV for enova365 / Symfonia) and creates/updates the listing.offer.status_changed → the CRM moves the stage.Parcel (raport/oferta) --webhook--> CRM biura (EstiCRM / ASARI / enova365 / Symfonia) --eksport CRM--> Otodom · OLX · Nieruchomosci-online · Nieruchomosci.pl · Gratka
Verified: Parcel CSV/XML/JSON format; EstiCRM and ASARI APIs exist (public docs); Otodom publishing via CRM (EstiCRM/ASARI KB). Conceptual (needs vendor partnership / spec): direct writes into enova365, Symfonia, ASARI, EstiCRM, Galactica Virgo and direct push to Otodom, OLX, Nieruchomosci-online, Nieruchomosci.pl, Gratka.
GET /api/v1/offers?id=…&view=buyer.GET /api/v1/parcel?id=…, view=buyer). No encumbrance, mortgage or credit data – Parcel never provides it.offer.* webhook to HQ; branches as company members.curl -H "X-API-Key: pk_test_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" "https://parcel-staging.imetroll.com/api/v1/offers?id=10&view=buyer"
{ "schema": "parcel.offer.v1",
"offer_ref": { "id": 10, "status": "active", "title": "Działka budowlana 2216 m² (PRZYKŁAD)", "asking_price": 789000, "currency": "PLN" },
"parcel": { "parcel_id": "141804_4.0006.9/5", "parcel_no": "9/5", "commune": "Piaseczno", "county": "powiat piaseczyński", "voivodeship": "mazowieckie" },
"parameters": { "area_m2": 2215.6, "area_ha": 0.2216, "perimeter_m": 197.1, "vertices": 12, "pl2000_zone": 7 },
"boundaries": { "wgs84_polygon": [[21.02314272, 52.08505105], …], "pl1992": [{ "nr": 1, "x_e": 641234.56, "y_n": 478901.23 }, …] },
"mpzp": { "covered": true, "plans": [{ "nazwa": "…", "uchwala": "…" }], "zones": [{ "symbol": "MN", "opis": "zabudowa mieszkaniowa jednorodzinna (PRZYKŁAD)" }] },
"map": { "parcel_map_url": "…/app.php?center=21.023562,52.084863&z=18", "geoportal_url": "https://mapy.geoportal.gov.pl/imap/Imgp_2.html?identifyParcel=141804_4.0006.9%2F5" },
"photos": ["https://…/zdjecie-1.jpg"] }
# full (agency) view additionally:
"agency": { "company_name": "Przykładowa Agencja Nieruchomości (PRZYKŁAD)", "nip": "1234563218", "regon": "123456785", "legal_form": "sp. z o.o.", "seat_address": "ul. Przykładowa 1, 00-001 Warszawa" },
"owner": { "name": "***", "anonymized": "***" },
"land_register": { "kw_number": "WA1M/********/*", "kw_persons": "***" }
POST https://crm.example.com/parcel-webhook
Content-Type: application/json
X-Parcel-Event: offer.status_changed
X-Parcel-Event-Id: evt_0f1e2d3c4b5a69788796a5b4c3d2e1f0
X-Parcel-Signature: t=1793554496,v1=5d41402abc4b2a76b9719d911017c592aa5b8c3e0e3f4a5b6c7d8e9f0a1b2c3d
{"id":"evt_0f1e2d3c4b5a69788796a5b4c3d2e1f0","type":"offer.status_changed","created_at":"2026-11-01T18:34:56+01:00","api_version":"v1",
"data":{"offer":{"schema":"parcel.offer.v1","offer_ref":{"id":10,"status":"reserved","asking_price":789000},"previous_status":"active",
"parcel":{"parcel_id":"141804_4.0006.9/5"},"owner":{"name":"***"},"land_register":{"kw_number":"WA1M/********/*","kw_persons":"***"}, …}}}
# signature check (Python)import hmac, hashlib, time
t, v1 = dict(p.split("=", 1) for p in request.headers["X-Parcel-Signature"].split(",")).values()
ok = abs(time.time() - int(t)) < 300 and hmac.compare_digest(v1, hmac.new(SECRET.encode(), f"{t}.".encode() + request.get_data(), hashlib.sha256).hexdigest())
Default 30 requests / min and 1000 / month per key. Headers X-RateLimit-Limit, X-RateLimit-Remaining; when exceeded 429 + Retry-After.
| HTTP | error |
|---|---|
| 400 | bad_id · id_or_address_required · bad_fmt |
| 401 | missing_or_bad_api_key · invalid_or_revoked_key |
| 404 | not_found |
| 429 | rate_limited · monthly_quota_exceeded |
API billing: coming soon (beta, free on staging). · Polski
Base /sandbox/v1, public key pk_sandbox_demo_parcel, webhook signing secret whsec_sandbox_demo. Fictional offers SBX-1..3 and parcels SBX_…; no GUGiK/EKW lookups. Changes (PATCH) visible only from your IP, reset daily at 03:00. Limits: 30 requests/min and 5 webhook tests/hour per IP; webhooks to public https only (443/8443). Get your own test key →
No account needed. Public sandbox key, fictional data, 30 requests/min per IP, nightly reset. Key: pk_sandbox_demo_parcel · Base: /sandbox/v1
curl -H "X-API-Key: pk_sandbox_demo_parcel" "https://parcel-staging.imetroll.com/sandbox/v1/offers"
We use only necessary cookies (login session, your cookie choice). We do not use analytics or advertising cookies. Cookie policy