Geokodowanie i walidacja adresów
GET /v1/geocode potwierdza, że adres istnieje w rejestrze PRG (GUGiK), i zwraca punkt budynku: współrzędne WGS84, kod pocztowy i identyfikator ulicy. Trzy tryby wywołania — polami (sym + number), wg nazwy miejscowości (locality) albo jednym ciągiem (address) — plus wersja wsadowa POST /v1/geocode/batch: do 50 adresów na jedno żądanie.
Gdy numeru nie ma w rejestrze, a ulica istnieje, odpowiedź sugeruje sąsiednie numery; niejasne nazwy miejscowości i ulic wracają jako krótkie listy kandydatów do zawężenia kolejnym zapytaniem.
GET /v1/geocode
Trzy tryby w jednym endpointcie: polami, wg nazwy albo jednym ciągiem adresu. Format=geojson zmienia odpowiedź na RFC 7946.
Sprawdź na żywo: /v1/geocode?address=Warszawa,%20ul.%20Anilinowa%202
| Nazwa | Wymagany | Opis |
|---|---|---|
address | — | Free-text Polish address ('Wrocław-Fabryczna, ul. Eugeniusza Horbaczewskiego 35'), parsed into locality/street/number internally — locality resolution reuses the exact+fuzzy name-search pipeline, so district strings ('Wrocław-Śródmieście') resolve to the same city. Mutually exclusive with sym, number, street, streetName, locality and postalCode; may only appear with limit. Additive `query` echo reports the parse (`cityResolved` distinguishes a bad split from an unknown address). |
sym | — | Locality SYM (7 digits, from /v1/localities). Required unless `address` or `locality` is given; mutually exclusive with locality. |
locality | — | Locality/city NAME (diacritics-insensitive) instead of a SYM — resolved through the locality index (exact matches all considered, fuzzy fallback otherwise). Several matches → result 'locality-ambiguous' with a population-ordered shortlist in `localities[]` (capped at 50, `localitiesTruncated` when cut); re-query fielded with sym=. Mutually exclusive with sym and address. |
postalCode | — | Optional narrowing hint for the locality mode: only localities the code officially serves (its PRG locality set, else the PNA name set) stay candidates — a code contradicting every name match answers result 'none'. Requires locality. |
number | — | House number ('21A'). Required unless `address` is given. |
street | — | Street SYM_UL (5 digits, from /v1/streets). Omit for rural 'locality + number' addresses. |
streetName | — | Street name prefix (diacritics-insensitive; 'rynek' finds 'ul. Rynek'), resolved via the ULIC registry. Mutually exclusive with street; several matches → result 'street-ambiguous' with candidates. |
limit | — | Maximum matches (1–50). |
format | — | 'geojson' answers an RFC 7946 FeatureCollection (every match a Feature) instead of the JSON envelope. |
Przykład
Tryb free-text (address=)
curl "https://teryt24.pl/v1/geocode?address=Warszawa,%20ul.%20Anilinowa%202"Odpowiedź:
{
"result": "exact",
"matches": [
{ "lat": 52.34742861543721, "lon": 20.945528669786594, "number": "2", "streetId": "00326", "postalCode": "03-149" }
],
"query": { "city": "Warszawa", "street": "Anilinowa", "number": "2", "numbers": ["2"], "range": false, "cityResolved": true }
}Tryb polowy (sym + street + number)
curl "https://teryt24.pl/v1/geocode?sym=0983988&street=12400&number=8"Odpowiedź:
{
"result": "exact",
"matches": [
{ "lat": 50.732269980089356, "lon": 16.640331777507814, "number": "8", "streetId": "12400", "postalCode": "58-200" }
]
}| Status | Opis |
|---|---|
200 | Resolution result — 'exact' (building points), 'street' (number unknown, suggestions provided), 'street-ambiguous' (streetName matched several streets), 'locality-ambiguous' (the locality name matched several localities; shortlist in `localities[]`) or 'none'. Address- and locality-mode responses carry the `query` echo (cityResolved records whether the locality token resolved). |
400 | Invalid query parameters. |
429 | Rate limit exceeded (60 requests/min/IP) or a plan's monthly quota exhausted. Includes `Retry-After` and `X-RateLimit-*` headers; the body's `code` distinguishes the two kinds. |
500 | Unexpected server failure (e.g. the database is unreachable). The body is deliberately generic — error detail lives in the server logs, never in the response. |
503 | Address dataset not available (POST /admin/ingest-prg). |
POST /v1/geocode/batch
Do 50 zapytań GET /v1/geocode w jednym wywołaniu — jeden slot limitera, kolejność zachowana, błędny adres nie psuje reszty partii.
Treść żądania (JSON)
| Nazwa | Wymagany/typ | Opis |
|---|---|---|
requests | array (1–50) | Każdy element to pola zapytania GET /v1/geocode (address albo sym/locality + number…), opcjonalnie z własnym identyfikatorem id. |
Przykład
Dwa adresy jednym żądaniem
curl -X POST "https://teryt24.pl/v1/geocode/batch" \
-H "Content-Type: application/json" \
-d '{"requests":[{"id":"a","address":"Warszawa, ul. Anilinowa 2"},{"id":"b","sym":"0983988","number":"8"}]}'{"requests":[{"id":"a","address":"Warszawa, ul. Anilinowa 2"},{"id":"b","sym":"0983988","number":"8"}]}Odpowiedź (skrócona — pokazano pierwsze wiersze):
{
"results": [
{ "id": "a", "status": "ok", "result": "exact", "matches": [ { "lat": 52.34742861543721, "lon": 20.945528669786594, "number": "2", "streetId": "00326", "postalCode": "03-149" } ], "query": { "city": "Warszawa", "street": "Anilinowa", "number": "2", "numbers": ["2"], "range": false, "cityResolved": true } },
{ "id": "b", "status": "ok", "result": "exact", "matches": [ { "lat": 50.72964828838264, "lon": 16.649854908143396, "number": "8", "streetId": "05345", "postalCode": "58-200" } ] }
]
}| Status | Opis |
|---|---|
200 | Successful response. |
400 | Invalid query parameters. |
429 | Rate limit exceeded (60 requests/min/IP) or a plan's monthly quota exhausted. Includes `Retry-After` and `X-RateLimit-*` headers; the body's `code` distinguishes the two kinds. |
500 | Unexpected server failure (e.g. the database is unreachable). The body is deliberately generic — error detail lives in the server logs, never in the response. |
Przeglądaj dane
Te same dane mają strony w przeglądarce — karty miejscowości i kodów pocztowych:
Wszystkie endpointy /v1 zwracają JSON, obsługują CORS i są objęte dokumentem openapi.json. Interaktywna wersja tej referencji: /docs.
Limity: 60 zapytań/min na IP bez klucza; klucz API (nagłówek X-API-Key) dostaje własny kubełek. Po przekroczeniu endpointy odpowiadają HTTP 429 z nagłówkiem Retry-After. Szczegóły: limity i klucze · zasady użycia.
Dane: GUS TERYT, punkty adresowe PRG (GUGiK), kody pocztowe GeoNames — przez teryt24.pl z linkiem do zasad użycia. Użycie wyłącznie po stronie serwera jest zwolnione.