teryt24.pl

teryt24.pl · API reference

Bulk address normalisation from CSV

POST /v1/bulk/addresses takes a CSV of addresses and returns a job (202): the file is processed in the background, row by row, through the SAME validation pipeline GET /v1/validate runs. The columns are named by the caller (query parameters) — the service NEVER guesses which column is the street. A named API key is REQUIRED (401 without one): the job stores the customer's personal data on the instance for the retention window and costs real work.

The result file carries the customer's ORIGINAL columns, with the service's columns beside them: the confirmed locality, street, house number, postal code and coordinates, the match kind per field, and the reasons the rows that were not confirmed were not confirmed. A value the register did not confirm is left EMPTY — never guessed. The rows split into four groups: matched, ambiguous, invalid and unmatched.

Re-uploading the same file (or the same Idempotency-Key) returns the EXISTING job instead of processing and billing it twice. The upload and its result are deleted when the retention window ends (24 hours by default), and the job answers 410 Gone from then on.

POST /v1/bulk/addresses

Upload the file (its content IS the request body, text/csv) and name the columns. The answer is a 202 with the job handle.

Parameters
NameRequiredDescription
locality—The column holding the locality — a name or a 7-digit SYM. Required unless `address` is given.
street—The column holding the street — a name or a 5-digit SYM_UL.
number—The column holding the house number.
postalCode—The column holding the postal code — it also narrows an ambiguous locality name.
address—The column holding the WHOLE address (one free-text field) — the alternative to the four separate columns.
id—The column identifying the row (echoed into the result).

Request body (JSON)

NameRequired/typDescription
<treść żądania>CSV (text/csv)The file, with a header row. UTF-8 (a BOM is fine), comma, semicolon or tab delimited.

Example

The upload

curl -X POST "https://teryt24.pl/v1/bulk/addresses?locality=miejscowosc&ulica=ulica&numer=nr&kod=kod&id=id" \
  -H "Content-Type: application/json" \
  -d 'id,miejscowosc,ulica,nr,kod
1,Wrocław,ul. Legnicka,61,53-331
2,Wrocław,ul. Legnicka,62,53-331'
id,miejscowosc,ulica,nr,kod
1,Wrocław,ul. Legnicka,61,53-331
2,Wrocław,ul. Legnicka,62,53-331

Response:

{
  "id": "0f3c1b7e-2f5a-4a1e-9c2d-6b1a2f0d4e11",
  "status": "queued",
  "filename": "adresy.csv",
  "rows": 2,
  "processed": 0,
  "matched": 0,
  "ambiguous": 0,
  "invalid": 0,
  "unmatched": 0,
  "error": null,
  "resultUrl": null
}
Responses
StatusDescription
200The same file was uploaded before: the EXISTING job is returned (`duplicate: true`) — the file is not processed or billed twice.
202The job was accepted: `{ id, status, rows, processed, matched, ambiguous, invalid, unmatched, resultUrl }`. Poll GET /v1/bulk/jobs/{id} for progress and GET /v1/bulk/jobs/{id}/result.csv for the result.
400Invalid query parameters.
401A named API key is required for bulk processing.
413The file has more rows than the configured limit.
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.

GET /v1/bulk/jobs/{id}

The job's state and progress: how many rows were processed and how they split (matched / ambiguous / invalid / unmatched).

Try it live: /v1/bulk/jobs/0f3c1b7e-2f5a-4a1e-9c2d-6b1a2f0d4e11

Parameters
NameRequiredDescription
id path✓The job id.

Example

The finished job

curl "https://teryt24.pl/v1/bulk/jobs/0f3c1b7e-2f5a-4a1e-9c2d-6b1a2f0d4e11"

Response:

{
  "id": "0f3c1b7e-2f5a-4a1e-9c2d-6b1a2f0d4e11",
  "status": "done",
  "rows": 2,
  "processed": 2,
  "matched": 1,
  "ambiguous": 0,
  "invalid": 0,
  "unmatched": 1,
  "resultUrl": "/v1/bulk/jobs/0f3c1b7e-2f5a-4a1e-9c2d-6b1a2f0d4e11/result.csv"
}
Responses
StatusDescription
200The job's state.
401A named API key is required.
404No such job (for this key).
410The job's files were deleted when the retention window ended.
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.

GET /v1/bulk/jobs/{id}/result.csv

The result file: the customer's columns unchanged + the service's columns. 409 while the job is still running; 410 once the files are gone.

Try it live: /v1/bulk/jobs/0f3c1b7e-2f5a-4a1e-9c2d-6b1a2f0d4e11/result.csv

Parameters
NameRequiredDescription
id path✓The job id.

Example

One result row (trimmed)

curl "https://teryt24.pl/v1/bulk/jobs/0f3c1b7e-2f5a-4a1e-9c2d-6b1a2f0d4e11/result.csv"

Response (truncated — first rows shown):

"id","miejscowosc","ulica","nr","kod","teryt24_status","teryt24_verdict","teryt24_locality","teryt24_locality_sym","teryt24_street","teryt24_street_id","teryt24_house_number","teryt24_postal_code","teryt24_lat","teryt24_lon","teryt24_match","teryt24_issues"
"1","Wrocław","ul. Legnicka","61","53-331","matched","valid","Wrocław","0983988","ul. Legnicka","12400","61","53-331","50.7322","16.6403","locality=exact;street=exact;houseNumber=exact;postalCode=exact",""
Responses
StatusDescription
200The result file.
401A named API key is required.
404No such job (for this key).
409The job has not finished yet.
410The job's files were deleted when the retention window ended.
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.

Browse the data

The same data has browsable pages — locality, street and postal-code cards:

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.