Introduction
The rastr API provides programmatic access to German geocoding and demographic data. Use it to convert addresses to coordinates, retrieve population statistics from Destatis, and manage API keys for your applications.
API Endpoints
4
Geocoding, with demographics built in
Region Coverage
Germany
Germany only
Protocol
REST
JSON over HTTPS
Authentication
All API endpoints require authentication. You can authenticate using either a Bearer JWT token (obtained via login) or an API key passed in the X-Api-Key header. API keys are recommended for programmatic access and server-side integrations.
API Key Authentication
Include your API key in the X-Api-Key header of every request. You can create and manage API keys from your dashboard.
cURL Example
curl -X GET "https://api.locationreport.com/geocode/location/52.524705,13.3932623" \
-H "X-Api-Key: your_api_key_here"JavaScript Example
const response = await fetch(
"https://api.locationreport.com/geocode/location/52.524705,13.3932623",
{
headers: {
"X-Api-Key": "your_api_key_here",
},
}
);
const data = await response.json();Keep your API keys secure. Never expose them in client-side code or public repositories. Rotate keys regularly if you suspect they have been compromised.
Geocoding
/geocode/address/{address}Accepts a text address in the path and returns coordinates with formatted address. Returns best match only. DE region only. Optional 'year' and 'quarter' query params select a specific dataset period. When 'fields=census' is set, the response includes a 'fields.census' object with population, age bands, marital status, average household size, and the resolved grid cell's corner coordinates, sourced from Destatis. 'dataSource' is 'census' or 'estimated' and 'effectiveQuarter' is 0-4 (both null when no dataset version resolves for the requested period). 'granularity' is a string: unknown, rooftop, rangeInterpolated, geometricCenter, approximate.
Parameters
| Name | Type | In | Required | Description |
|---|---|---|---|---|
| address | string | path | Required | Full address text (e.g. "71 Oranienburger Straße, 10117 Berlin") |
| fields | string | query | Optional | Comma-separated list of enrichment fields (e.g. "census") |
| year | integer | query | Optional | Dataset year to query (default: latest available). |
| quarter | integer | query | Optional | Dataset quarter: 0 for the annual/census snapshot, 1-4 for a specific quarter (default: latest available for the given year). |
| language | string | query | Optional | Language of the returned address text: "de" or "en". Defaults to "de". |
Response
{
"results": [
{
"location": {
"latitude": 52.524705,
"longitude": 13.3932623
},
"granularity": "rooftop",
"formattedAddress": "Oranienburger Str. 71, 10117 Berlin, Germany",
"addressComponents": [
{
"types": [
"street_number"
],
"longText": "71",
"shortText": "71",
"languageCode": "de"
},
{
"types": [
"route"
],
"longText": "Oranienburger Straße",
"shortText": "Oranienburger Str.",
"languageCode": "de"
},
{
"types": [
"postal_code"
],
"longText": "10117",
"shortText": "10117",
"languageCode": "de"
},
{
"types": [
"locality"
],
"longText": "Berlin",
"shortText": "Berlin",
"languageCode": "de"
},
{
"types": [
"country"
],
"longText": "Germany",
"shortText": "DE",
"languageCode": "de"
}
],
"types": [
"street_address"
],
"fields": {
"census": {
"population": 3421,
"datasetYear": 2022,
"dataSource": "census",
"effectiveQuarter": 0,
"ageUnder10": 210,
"age10To19": 260,
"age20To29": 480,
"age30To39": 610,
"age40To49": 540,
"age50To59": 470,
"age60To69": 390,
"age70To79": 300,
"age80AndOver": 161,
"single": 1850,
"married": 1120,
"widowed": 240,
"divorced": 211,
"averageHouseholdSize": 1.8,
"cellBounds": {
"southWest": {
"latitude": 52.5241,
"longitude": 13.3925
},
"southEast": {
"latitude": 52.5241,
"longitude": 13.3941
},
"northEast": {
"latitude": 52.5253,
"longitude": 13.3941
},
"northWest": {
"latitude": 52.5253,
"longitude": 13.3925
}
}
}
}
}
]
}cURL Example
curl -X GET "https://api.locationreport.com/geocode/address/71%20Oranienburger%20Stra%C3%9Fe%2C%2010117%20Berlin?fields=census" \
-H "X-Api-Key: your_api_key"/geocode/addressAccepts a text address or structured fields in the query and returns coordinates. Returns best match only. DE region only. Optional 'year' and 'quarter' query params select a specific dataset period. When 'fields=census' is set, the response includes a 'fields.census' object with population, age bands, marital status, average household size, and the resolved grid cell's corner coordinates, sourced from Destatis. 'dataSource' is 'census' or 'estimated' and 'effectiveQuarter' is 0-4 (both null when no dataset version resolves for the requested period). 'granularity' is a string: unknown, rooftop, rangeInterpolated, geometricCenter, approximate.
Parameters
| Name | Type | In | Required | Description |
|---|---|---|---|---|
| street | string | query | Optional | Street name |
| houseNumber | string | query | Optional | House / building number |
| postalCode | string | query | Optional | Postal code (PLZ) |
| city | string | query | Optional | City name |
| country | string | query | Optional | Country name or code (default: DE) |
| fields | string | query | Optional | Comma-separated enrichment fields (e.g. "census") |
| year | integer | query | Optional | Dataset year to query (default: latest available). |
| quarter | integer | query | Optional | Dataset quarter: 0 for the annual/census snapshot, 1-4 for a specific quarter (default: latest available for the given year). |
| language | string | query | Optional | Language of the returned address text: "de" or "en". Defaults to "de". |
Response
{
"results": [
{
"location": {
"latitude": 52.524705,
"longitude": 13.3932623
},
"granularity": "rooftop",
"formattedAddress": "Oranienburger Str. 71, 10117 Berlin, Germany",
"addressComponents": [],
"types": [
"street_address"
],
"fields": {
"census": {
"population": 3421,
"datasetYear": 2022,
"dataSource": "census",
"effectiveQuarter": 0,
"ageUnder10": 210,
"age10To19": 260,
"age20To29": 480,
"age30To39": 610,
"age40To49": 540,
"age50To59": 470,
"age60To69": 390,
"age70To79": 300,
"age80AndOver": 161,
"single": 1850,
"married": 1120,
"widowed": 240,
"divorced": 211,
"averageHouseholdSize": 1.8,
"cellBounds": {
"southWest": {
"latitude": 52.5241,
"longitude": 13.3925
},
"southEast": {
"latitude": 52.5241,
"longitude": 13.3941
},
"northEast": {
"latitude": 52.5253,
"longitude": 13.3941
},
"northWest": {
"latitude": 52.5253,
"longitude": 13.3925
}
}
}
}
}
]
}cURL Example
curl -X GET "https://api.locationreport.com/geocode/address?street=Oranienburger%20Stra%C3%9Fe&houseNumber=71&postalCode=10117&city=Berlin&fields=census" \
-H "X-Api-Key: your_api_key"/geocode/location/{latitude},{longitude}Accepts latitude/longitude in the path and returns formatted address with structured breakdown. DE region only. Optional 'year' and 'quarter' query params select a specific dataset period. When 'fields=census' is set, the response includes a 'fields.census' object with population, age bands, marital status, average household size, and the resolved grid cell's corner coordinates, sourced from Destatis. 'dataSource' is 'census' or 'estimated' and 'effectiveQuarter' is 0-4 (both null when no dataset version resolves for the requested period). 'granularity' is a string: unknown, rooftop, rangeInterpolated, geometricCenter, approximate.
Parameters
| Name | Type | In | Required | Description |
|---|---|---|---|---|
| latitude | number | path | Required | WGS84 latitude (e.g. 52.524705) |
| longitude | number | path | Required | WGS84 longitude (e.g. 13.3932623) |
| fields | string | query | Optional | Comma-separated enrichment fields (e.g. "census") |
| year | integer | query | Optional | Dataset year to query (default: latest available). |
| quarter | integer | query | Optional | Dataset quarter: 0 for the annual/census snapshot, 1-4 for a specific quarter (default: latest available for the given year). |
| language | string | query | Optional | Language of the returned address text: "de" or "en". Defaults to "de". |
Response
{
"results": [
{
"location": {
"latitude": 52.524705,
"longitude": 13.3932623
},
"granularity": "rooftop",
"formattedAddress": "Oranienburger Str. 71, 10117 Berlin, Germany",
"addressComponents": [],
"types": [
"street_address"
],
"fields": {
"census": {
"population": 3421,
"datasetYear": 2022,
"dataSource": "census",
"effectiveQuarter": 0,
"ageUnder10": 210,
"age10To19": 260,
"age20To29": 480,
"age30To39": 610,
"age40To49": 540,
"age50To59": 470,
"age60To69": 390,
"age70To79": 300,
"age80AndOver": 161,
"single": 1850,
"married": 1120,
"widowed": 240,
"divorced": 211,
"averageHouseholdSize": 1.8,
"cellBounds": {
"southWest": {
"latitude": 52.5241,
"longitude": 13.3925
},
"southEast": {
"latitude": 52.5241,
"longitude": 13.3941
},
"northEast": {
"latitude": 52.5253,
"longitude": 13.3941
},
"northWest": {
"latitude": 52.5253,
"longitude": 13.3925
}
}
}
}
}
]
}cURL Example
curl -X GET "https://api.locationreport.com/geocode/location/52.524705,13.3932623?fields=census" \
-H "X-Api-Key: your_api_key"/geocode/locationAccepts latitude/longitude as query parameters and returns formatted address with structured breakdown. DE region only. Optional 'year' and 'quarter' query params select a specific dataset period. When 'fields=census' is set, the response includes a 'fields.census' object with population, age bands, marital status, average household size, and the resolved grid cell's corner coordinates, sourced from Destatis. 'dataSource' is 'census' or 'estimated' and 'effectiveQuarter' is 0-4 (both null when no dataset version resolves for the requested period). 'granularity' is a string: unknown, rooftop, rangeInterpolated, geometricCenter, approximate.
Parameters
| Name | Type | In | Required | Description |
|---|---|---|---|---|
| latitude | number | query | Required | WGS84 latitude |
| longitude | number | query | Required | WGS84 longitude |
| fields | string | query | Optional | Comma-separated enrichment fields (e.g. "census") |
| year | integer | query | Optional | Dataset year to query (default: latest available). |
| quarter | integer | query | Optional | Dataset quarter: 0 for the annual/census snapshot, 1-4 for a specific quarter (default: latest available for the given year). |
| language | string | query | Optional | Language of the returned address text: "de" or "en". Defaults to "de". |
Response
{
"results": [
{
"location": {
"latitude": 52.524705,
"longitude": 13.3932623
},
"granularity": "rooftop",
"formattedAddress": "Oranienburger Str. 71, 10117 Berlin, Germany",
"addressComponents": [],
"types": [
"street_address"
],
"fields": {
"census": {
"population": 3421,
"datasetYear": 2022,
"dataSource": "census",
"effectiveQuarter": 0,
"ageUnder10": 210,
"age10To19": 260,
"age20To29": 480,
"age30To39": 610,
"age40To49": 540,
"age50To59": 470,
"age60To69": 390,
"age70To79": 300,
"age80AndOver": 161,
"single": 1850,
"married": 1120,
"widowed": 240,
"divorced": 211,
"averageHouseholdSize": 1.8,
"cellBounds": {
"southWest": {
"latitude": 52.5241,
"longitude": 13.3925
},
"southEast": {
"latitude": 52.5241,
"longitude": 13.3941
},
"northEast": {
"latitude": 52.5253,
"longitude": 13.3941
},
"northWest": {
"latitude": 52.5253,
"longitude": 13.3925
}
}
}
}
}
]
}cURL Example
curl -X GET "https://api.locationreport.com/geocode/location?latitude=52.524705&longitude=13.3932623&fields=census" \
-H "X-Api-Key: your_api_key"Migrating from Google Maps Geocoding API
If you're currently using the Google Maps Geocoding API, migrating to the rastr API is straightforward. Below is a side-by-side comparison to help you understand the differences and plan your migration.
| Dimension | Google Maps Geocoding API | rastr API |
|---|---|---|
| Endpoint Structure | RESTful endpoint with query parameters (address=, key=, language=, etc.) | RESTful endpoint with path parameters (/geocode/address/{address}) and X-Api-Key header |
| Authentication | URL parameter (key=YOUR_API_KEY) | HTTP header (X-Api-Key: YOUR_API_KEY) |
| Response Format | Nested JSON with geometry.bounds, geometry.location, address_components arrays | Flat JSON with latitude, longitude, formattedAddress, plus demographics data |
| Pricing Model | Pay-per-use ($5 per 1,000 requests), volume discounts available | Prepaid credits or subscription plans with predictable monthly costs |
| Rate Limits | Varies by plan (50 QPS standard, 100+ QPS premium) | Plan-based rate limits with burst allowance |
| Region Coverage | Worldwide coverage, ~200 countries | Germany-only coverage with census-grade Destatis data |
| Demographics Data | No built-in demographics — requires separate API or data source | Built-in population, age distribution, and household data from Destatis Zensus 2022 and estimates to 2026 |
Code Migration Example
The following example shows how to migrate a simple forward geocoding request from Google Maps to rastr. The key differences are the URL structure, authentication header, and flatter response format.
const API_KEY = "YOUR_GOOGLE_API_KEY";
const address = "Oranienburger Straße 71, Berlin";
const response = await fetch(
`https://maps.googleapis.com/maps/api/geocode/json?` +
`address=${encodeURIComponent(address)}&key=${API_KEY}`
);
const data = await response.json();
// Extract coordinates from nested response
const lat = data.results[0].geometry.location.lat;
const lng = data.results[0].geometry.location.lng;const API_KEY = "YOUR_LR_API_KEY";
const address = "Oranienburger Straße 71, Berlin";
const response = await fetch(
`https://api.locationreport.com/geocode/address/` +
`${encodeURIComponent(address)}`,
{
headers: { "X-Api-Key": API_KEY }
}
);
const data = await response.json();
// Flat response with coordinates + demographics
const { latitude, longitude } = data;Key Differences
- ✓Authentication via HTTP header instead of URL parameter — your API key is never exposed in server logs or browser history.
- ✓Flat response structure — no need to navigate nested geometry.location objects to extract coordinates.
- ✓Demographics included — population statistics, age distribution, and household data can be added with every geocoding request.
- ✓Germany-optimized results — higher accuracy for German addresses with Destatis data enrichment not available elsewhere.
Need an endpoint or field that isn't here?
Tell us what's missing — we read every request.