teryt24.pl

teryt24.pl · API reference

The TERYT registry change feed

GUS publishes "pliki aktualizacyjne": the DIFFS between catalogue states. GET /v1/changes serves them as a feed — with the catalogue state the change belongs to, and with GUS's own field names in the `before` and `after` blocks (the feed invents no schema of its own).

Three meanings, stated plainly. A DELETION means the object left the catalogue — it does NOT mean the address became invalid. A REORDERING (the type "reordered", ULIC's "Z") is a FORMATTING change: the part of the street's name that decides its alphabetical position changed — it has its own type, so it can be filtered out. The dates are the CATALOGUE STATES (GUS's StanPrzed/StanPo), not the moment the file was published.

The feed starts with the first ingested update file: the registry's earlier history is NOT reconstructed, because the diff files only describe the states they were generated for. `meta.coverage.complete` says so plainly. Until the first file is fetched the endpoint answers 503.

GET /v1/changes

The change feed: filters by catalogue state, registry and change type. Newest first.

Try it live: /v1/changes?dataset=simc&since=2026-10-01&limit=2

Parameters
NameRequiredDescription
since—The catalogue state to start from (YYYY-MM-DD). Changes whose "after" state is on or after this date are returned.
until—The catalogue state to stop at (YYYY-MM-DD), inclusive.
dataset—The registry: terc (administrative units) | simc (localities) | ulic (streets). All three when omitted.
type—The change type(s), comma-separated: added, modified, moved, renamed, reordered, deleted. All of them when omitted.
limit—Maximum changes per page (1–200).
offset—0-based, skips the first N changes (max 10000).

Example

Locality changes

curl "https://teryt24.pl/v1/changes?dataset=simc&since=2026-10-01&limit=2"

Response (truncated — first rows shown):

{
  "changes": [
    {
      "dataset": "simc",
      "type": "renamed",
      "correctionType": "Z",
      "stanBefore": "2026-10-12",
      "stanAfter": "2026-11-09",
      "identityBefore": "0983988",
      "identityAfter": "0983988",
      "nameBefore": "Dzierżoniów",
      "nameAfter": "Dzierżoniów Śląski",
      "before": { "Stan": "2026-10-12", "Woj": "14", "Pow": "65", "Gmi": "03", "Rodz": "01", "Nazwa": "Dzierżoniów" },
      "after": { "Stan": "2026-11-09", "Woj": "14", "Pow": "65", "Gmi": "03", "Rodz": "01", "Nazwa": "Dzierżoniów Śląski" }
    }
  ],
  "meta": {
    "total": 1,
    "offset": 0,
    "limit": 2,
    "coverage": { "from": "2026-10-12", "to": "2026-11-09", "ingestedAt": "2026-11-10T03:12:44.000Z", "complete": false }
  }
}
Responses
StatusDescription
200The changes, newest first, plus `meta.coverage` — the states the feed covers, when it was last ingested, and the fact that the earlier history is not reconstructed.
400Invalid query parameters.
429Rate 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.
500Unexpected server failure (e.g. the database is unreachable). The body is deliberately generic — error detail lives in the server logs, never in the response.

Browse the data

The changes concern the same objects that have browsable pages:

All /v1 endpoints return JSON, speak CORS and are covered by the openapi.json document. Interactive version of this reference: /en/docs.

Limits: 60 requests/min per IP without a key; an API key (the X-API-Key header) gets its own bucket. Over the limit the endpoints answer HTTP 429 with a Retry-After header. Details: limits & keys · usage policy.

Attribution is a condition of use. When you present results in an application, website, map or report, display: Data: GUS TERYT, PRG address points (GUGiK), GeoNames postal codes — via teryt24.pl with a link to the usage policy. Server-side-only use is exempt.