A RESTful API wrapper for libpostal, a C library for parsing and normalizing street addresses around the world.
Fork Notice: This project is a fork of johnlonganecker/libpostal-rest with additional features and maintenance updates.
- Batch Processing – Process multiple addresses in a single API call.
- Updated Dependencies – Brought up to date with newer Go and library versions.
- Parser Options – Specify optional
languageandcountryhints for improved parsing accuracy. - Docker Support – Prebuilt images and Docker Compose setup for easy deployment.
The easiest way to run the service is using the prebuilt Docker image.
You need to mount a volume containing the libpostal data files.
docker run -p 8080:8080 -v ./data:/data rezaq/libpostal-rest:alpineor for Senzing model:
docker run -p 8080:8080 -e MODEL=senzing -v ./data:/data rezaq/libpostal-rest:alpineFor development or building from source, use Docker Compose.
- Clone the repository.
- Set the
LIBPOSTAL_DATAenvironment variable (or rely on the default./data). - Run the service.
# Option 1: Default (looks for ./data)
docker compose up --build
# Option 2: Custom data path
LIBPOSTAL_DATA=/path/to/your/libpostal/data docker-compose up --build- Go 1.23+
- libpostal C library installed
Build the binary and run:
# Build
go build -o libpostal-rest .
# Run
./libpostal-restRun directly without building:
go run .Examples with environment variables:
export LISTEN_HOST=0.0.0.0
export LISTEN_PORT=8080
export LOG_LEVEL=info
# build + run
go build -o libpostal-rest .
./libpostal-rest
# or run directly
LISTEN_HOST=0.0.0.0 LISTEN_PORT=8080 LOG_LEVEL=info go run .| Method | Endpoint | Description |
|---|---|---|
| GET | /health | Health check |
| POST | /parser | Parse single address |
| POST | /parser/batch | Parse multiple addresses |
| POST | /expand | Expand/normalize single address |
| POST | /expand/batch | Expand multiple addresses |
| POST | /expandparser | Expand and parse single address |
| POST | /expandparser/batch | Expand and parse multiple addresses |
| Variable | Description | Default |
|---|---|---|
| LISTEN_HOST | Hostname or IP to bind | 0.0.0.0 |
| LISTEN_PORT | Port the server listens on | 8080 |
| LOG_LEVEL | Global log level (debug, info, warn, error, fatal, panic) |
info |
| LOG_STRUCTURED | If true, output structured JSON logs |
false |
| PROMETHEUS_ENABLED | Enable Prometheus metrics endpoint | false |
| PROMETHEUS_PORT | Port for Prometheus metrics | 9090 |
Parse an address into labeled components.
curl -X POST -H 'Content-Type: application/json' \
-d '{"query":"100 main st buffalo ny"}' \
http://localhost:8080/parserWith language/country hints:
curl -X POST -H 'Content-Type: application/json' \
-d '{"query":"100 main st buffalo ny","language":"en","country":"us"}' \
http://localhost:8080/parserResponse:
[
{ "label": "house_number", "value": "100" },
{ "label": "road", "value": "main st" },
{ "label": "city", "value": "buffalo" },
{ "label": "state", "value": "ny" }
]Normalize and expand an address into possible variations.
curl -X POST -H 'Content-Type: application/json' \
-d '{"query":"100 main st buffalo ny"}' \
http://localhost:8080/expandWith language option:
curl -X POST -H 'Content-Type: application/json' \
-d '{"query":"100 main st buffalo ny","langs":["en"]}' \
http://localhost:8080/expandResponse:
[
"100 main saint buffalo ny",
"100 main saint buffalo new york",
"100 main street buffalo ny",
"100 main street buffalo new york"
]curl -X POST -H 'Content-Type: application/json' \
-d '{"query":"100 main st buffalo ny"}' \
http://localhost:8080/expandparserResponse:
[
{
"data": "100 main st buffalo ny",
"parsed": [
{ "label": "house_number", "value": "100" },
{ "label": "road", "value": "main st" },
{ "label": "city", "value": "buffalo" },
{ "label": "state", "value": "ny" }
],
"type": "query"
},
{
"data": "100 main saint buffalo ny",
"parsed": [
{ "label": "house_number", "value": "100" },
{ "label": "road", "value": "main" },
{ "label": "city", "value": "saint buffalo" },
{ "label": "state", "value": "ny" }
],
"type": "expansion"
},
{
"data": "100 main saint buffalo new york",
"parsed": [
{ "label": "house_number", "value": "100" },
{ "label": "road", "value": "main" },
{ "label": "city", "value": "saint buffalo" },
{ "label": "state", "value": "new york" }
],
"type": "expansion"
},
{
"data": "100 main street buffalo ny",
"parsed": [
{ "label": "house_number", "value": "100" },
{ "label": "road", "value": "main street" },
{ "label": "city", "value": "buffalo" },
{ "label": "state", "value": "ny" }
],
"type": "expansion"
},
{
"data": "100 main street buffalo new york",
"parsed": [
{ "label": "house_number", "value": "100" },
{ "label": "road", "value": "main street" },
{ "label": "city", "value": "buffalo" },
{ "label": "state", "value": "new york" }
],
"type": "expansion"
}
]Process multiple addresses in one request. All batch endpoints accept an array of request objects with the same shape as the single-request body (including optional language, country, langs, etc.).
curl -X POST -H 'Content-Type: application/json' \
-d '[
{ "query": "100 main st buffalo ny" },
{ "query": "781 Franklin Ave Brooklyn NY" }
]' \
http://localhost:8080/parser/batchcurl -X POST -H 'Content-Type: application/json' \
-d '[
{ "query": "100 main st buffalo ny" }
]' \
http://localhost:8080/expand/batchcurl -X POST -H 'Content-Type: application/json' \
-d '[
{ "query": "100 main st buffalo ny" }
]' \
http://localhost:8080/expandparser/batchLogging has been implemented using zerolog, a super-fast structured logger outputting JSON. However, zerolog also allows outputting non-structured ("pretty printed") log lines, which is the default setting. zerolog also supports different log levels which are as follows:
panicfatalerrorwarninfodebugtrace
For example, to change the default log level from info to debug one would set the following environment variable:
export LOG_LEVEL='debug'Please note, if the string set in the environment variable is not one of the valid ones listed above, the service will log a warning and use the default level
info.
The service has been instrumented with the Prometheus client library. By default metrics collection and the Prometheus endpoint are disabled. It can be enabled by setting the environment variable PROMETHEUS_ENABLED to true. Once enabled, the metrics can be scraped at the following endpoint:
http://<LISTEN_HOST>:<PROMETHEUS_PORT>/metrics
The metrics endpoint exposes the default Go metrics as well as the following custom metrics of the service:
libpostal_expand_reqs_total- The total number of processed expand requestslibpostal_expand_durations_historgram_ms- Latency distributions of expand calls in millisecondslibpostal_parse_reqs_total- The total number of processed parse requestslibpostal_parse_durations_historgram_ms- Latency distributions of parse calls in millisecondslibpostal_expandparse_reqs_total- The total number of processed expandparse requestslibpostal_expandparse_durations_historgram_ms- Latency distributions of expandparse calls in milliseconds