API for postal codes, area codes and places
The postleitzahl.net JSON API returns the matching place, the country and all linked postal codes and area codes for postal codes, area codes or place names.
Authentication
An API key is required for every request. Pass it either in the X-Api-Token header, as Authorization: Bearer <TOKEN> or as the query parameter token.
Endpoint
You can pass the country and the search term in the path or as parameters. Both notations return the same response in JSON format.
https://www.postleitzahl.net/api/{country}/{query}
https://www.postleitzahl.net/api?country={country}&q={query} Try it
Here you can try out the API without an API key. An API key is required for requests from your own application.
{
"status": "success",
"country": "Uzbekistan",
"countryCode": "UZ",
"place": "G‘ijduvon",
"postcode": "500200",
"areacode": "65",
"query": "500200",
"type": "postcode"
} Query types
The API detects the request type on its own: if the input matches the postal code format of the country, it first searches for a postal code. Other sequences of digits are treated as an area code, all other input as a place name. If the search returns no match, it checks the remaining types. Use the type parameter to set the type explicitly.
| Example | Type | Meaning |
|---|---|---|
/api/de/32423or/api?country=de&q=32423 | postcode | postal code |
/api/de/0571or/api?country=de&q=0571 | prefix | telephone area code |
/api/de/Mindenor/api?country=de&q=Minden | place | place name |
Parameters
| Parameter | Effect |
|---|---|
country | Required: two-letter country code, e.g. de, nl or gb – either in the path (/api/de/32423) or as a parameter (country=de) |
q | Search term as a parameter instead of in the path, e.g. /api?country=de&q=Minden |
type | Sets the request type: postcode, prefix or place |
fields | Comma-separated list of the desired fields, e.g. ?fields=place,postcode |
lang | language of the translatable fields, e.g. ?lang=en |
callback | Name of the callback function for JSONP |
token | API key as a query parameter, if you do not pass it in the header |
Localization
Use the lang parameter to set the language of the response. The name of the country is translated; place names keep their original spelling. If lang is missing, the Accept-Language header of your request applies. Unknown language codes are ignored.
de ar be bg bs ca cs da el en es et fa fi fr ga he hi hr hu hy id is it ja ka km ko lo lt lv mk mn ms mt ne nl no pl pt ro ru sk sl sq sr sv th tr uk vi zh
curl -H "X-Api-Token: plz_…" "https://www.postleitzahl.net/api/de/32423?lang=en"
{ "status": "success", "country": "Germany", "countryCode": "DE", "place": "Minden", "postcode": "32423", "query": "32423", "type": "postcode" } Response fields
| Field | Content | Example |
|---|---|---|
status | Result of the request: success or fail | "success" |
query | The submitted request | "500200" |
type | Detected request type: postcode, prefix or place | "postcode" |
country | Name of the country, translatable with lang | "Germany" |
countryCode | Country code according to ISO 3166-1 Alpha-2 | "UZ" |
place | Place name; a list if there are several matches | "Minden" |
postcode | Postal code of the place; a list if there are several | ["32423","32425","32427","32429"] |
areacode | Telephone area code of the place; a list if there are several | "0571" |
message | Only with status fail: short description of the error | "not found" |
Usage limit
Each API key allows 20 requests per minute. Every response contains the number of requests still available in the current minute in the X-Rl header and the seconds until the start of the next minute in the X-Ttl header.
{
"status": "fail",
"code": 1008,
"message": "rate limit exceeded",
"query": "500200"
} Error responses
If a request fails, the response contains "status": "fail", a unique error code in the code field and a short message in the message field. In your application, evaluate the error code, not the text of the message.
| HTTP | Code | message | Cause |
|---|---|---|---|
| 401 | 1001 | missing api token | The request does not contain an API key. |
| 401 | 1002 | invalid api token | The API key is unknown or invalid. |
| 400 | 1003 | missing or unknown country | The country code is missing or unknown. |
| 400 | 1004 | missing query | The request does not contain a search term. |
| 400 | 1005 | query too long | The search term is longer than 80 characters. |
| 404 | 1006 | not found | No entry was found for the search term. |
| 429 | 1007 | try-out limit exceeded | When trying it out on this page, at most 10 requests are possible in 5 minutes. |
| 429 | 1008 | rate limit exceeded | The limit of 20 requests per minute has been reached. Requests are possible again from the next minute. |
| 429 | 1009 | try-out banned for 60 minutes | The try-out limit was exceeded 3 times in a row. Trying it out is then blocked for 60 minutes. |
| 400 | 1010 | bad request | The request contains characters that are not allowed in the path. Send the search term URL-encoded or in the parameter q. |
| 503 | 1011 | service unavailable | The service is temporarily unavailable. Repeat the request after the number of seconds in the Retry-After header. |
| 404 | 1012 | no postcode system in this country | The country has no postcode system. Place names and area codes are still found; the field postcode stays empty. |
Examples
curl -H "X-Api-Token: plz_…" https://www.postleitzahl.net/api/uz/500200 curl -H "X-Api-Token: plz_…" "https://www.postleitzahl.net/api/gb/SW1A%201AA" curl -H "Authorization: Bearer plz_…" "https://www.postleitzahl.net/api/de/Minden?fields=place,postcode" curl "https://www.postleitzahl.net/api?country=de&q=0571&type=prefix&token=plz_…"
Data sources
The data comes from the official directories of the respective countries and from open sources such as GeoNames, OpenStreetMap and Wikidata. In the EU member states, the NUTS classification of Eurostat and the TERCET table of the European Commission complement the assignment of postal codes to regions.
Publish properties from Propstack
Agents working with Propstack publish their properties on postleitzahl.net automatically. The connection uses the Propstack REST API (V1 or V2): properties, project data and images are fetched directly via HTTP request. This is faster than a file export and not tied to the rigid structures of the OpenImmo XML format.
How to connect Propstack
- In Propstack, create a key for API V2 or V1 under Verwaltung > API-Schlüssel (Administration > API keys) with read access to properties.
- Sign in to postleitzahl.net and store the key under My area > Integrations. We test it immediately and store it encrypted.
- Start the sync. After that we sync your released properties automatically at regular intervals.
What is transferred
We import non-archived properties whose status is not marked as non-public in Propstack. Private images are not transferred.
| Listing data | Propstack fields |
|---|---|
| Title and descriptions | title, description_note, location_note, furnishing_note, other_note |
| Address and location | street, house_number, zip_code, city, lat, lng, hide_address, country, region |
| Price, service charges, deposit, commission | price, base_rent, service_charge, heating_costs, heating_costs_in_service_charge, deposit, courtage |
| Areas, rooms, floor | living_space, plot_area, usable_floor_space, property_space_value, number_of_rooms, number_of_bed_rooms, number_of_bath_rooms, floor |
| Marketing type and property type | marketing_type, rs_type, rs_category |
| Features | built_in_kitchen, balcony, guest_toilet, garden, cellar, lift, barrier_free, chimney, air_conditioning |
| Year built and energy certificate | construction_year, energy_efficiency_class, energy_certificate_construction_year |
| Images and floor plans | images (is_floorplan, is_private, title, position), floorplans |
Read and write back
Read: postleitzahl.net requests the released properties page by page and applies changes at the next sync. Properties that are no longer released are ended as listings.
GET https://api.propstack.de/v2/property_statuses
GET https://api.propstack.de/v2/properties?status={public statuses}&page=1&per=100
GET https://api.propstack.de/v1/units?with_meta=1&expand=1&status={public statuses}
X-API-KEY: •••••••• Write back: Once a listing is live, postleitzahl.net adds a link to the exposé to the property in Propstack. The link is not passed on to other portals.
POST https://api.propstack.de/v2/properties/{id}/links
{ "title": "postleitzahl.net", "url": "https://www.postleitzahl.net/expose/{listing}", "is_private": true } Developers will find the technical details in the official Propstack API documentation.
Review and publication
Like all listings, new and changed listings go live only after review by our editorial team. If required details are missing, the listing stays a draft in your properties and you complete it in the editor.
The API key is stored encrypted and only sent to api.propstack.de. After saving you only see its last 4 characters.
Transfer properties via OpenImmo and FTP
Most real estate portals in Germany receive properties in OpenImmo format via FTP. So does postleitzahl.net: you get your own FTP account with server, username and password. Any agent software with OpenImmo export – Propstack, for example – uploads your released properties there.
How to set up the export
- Create your FTP account under My area > Integrations.
- In Propstack, add a portal of type “FTP nach OpenImmo-Standard” under Verwaltung > Portale and enter server, username and password.
- Release a property for the portal. Propstack then exports a ZIP file with the OpenImmo XML and the images to the FTP server.
- postleitzahl.net reads new files regularly and creates or updates the listings.
Contents of the ZIP file
| File | Contents |
|---|---|
*.xml | Property data according to the OpenImmo schema (openimmo with anbieter and immobilie) |
*.jpg, *.png, *.gif, *.webp | Images and floor plans as attachments of the property |
*.pdf | Floor plans and documents |
Limits per ZIP file: at most 300 MB unpacked, 500 files and 20 MB per file. Images are matched by file name; other file types are ignored.
How the data is processed
| XML element | Effect |
|---|---|
verwaltung_techn/objektnr_extern | Fixed identifier of the property: we recognise it by this in every later transfer. |
aktion aktionart="CHANGE" | Create or update (also when no action is given). |
aktion aktionart="DELETE" | End the listing. |
aktion aktionart="REFERENZ" | Reference property (sold or let): end the listing. |
uebertragung umfang="VOLL" | Full transfer: properties no longer in the file are ended. |
uebertragung umfang="TEIL" | Partial transfer: only the properties contained are changed. |
Review and publication
Like all listings, new and changed listings go live only after review by our editorial team. If required details are missing, the listing stays a draft in your properties and you complete it in the editor.
Tip: if you use Propstack, the Propstack API is the faster choice – changes arrive without a file export.

