The Mapzen Libpostal API

The Mapzen Libpostal API (application programming interface) is a REST-based interface to the Libpostal C library for parsing and normalizing street addresses in to data structures using OpenStreetMap data.

Al Barrentine, who is Libpostal’s author, wrote an exhaustive blog post describing what Libpostal is and and how it works. It is aimed at a technical audience so we’ll just excerpt the short version here:

Libpostal uses machine learning and is informed by tens of millions of real-world addresses from OpenStreetMap. The entire pipeline for training the models is open source. Since OSM is a dynamic data set with thousands of contributors and the models are retrained periodically, improving them can be as easy as contributing addresses to OSM.

Each country’s addressing system has its own set of conventions and peculiarities and libpostal is designed to deal with practically all of them. It currently supports normalizations in 60 languages and can parse addresses in more than 100 countries. Geocoding using libpostal as a preprocessing step becomes drastically simpler and more consistent internationally.

The Libpostal API has two endpoints that are exposed as HTTP GET requests, returning JSON-formatted results.

GET /expand ?address=ADDRESS

The /expand endpoint analyzes an address string and returns a list of normalized equivalent strings.

Arguments

Parameter Sample Value Required
address “475 Sansome St San Francisco CA” yes

Example

curl -s -X GET 'https://libpostal.mapzen.com/expand?address=475+Sansome+St+San+Francisco+CA' | python -mjson.tool
[
    "475 sansome saint san francisco california",
    "475 sansome saint san francisco ca",
    "475 sansome street san francisco california",
    "475 sansome street san francisco ca"
]

GET /parse ?address=ADDRESS

The /parse endpoint analyzes an address string and returns its component parts (street number, street name, city and so on).

Arguments

Parameter Sample Value Required
address “475 Sansome St San Francisco CA” yes
format keys no

Example

curl -s -X GET 'https://libpostal.mapzen.com/parse?address=475+Sansome+St+San+Francisco+CA' | python -mjson.tool
[
    {
        "label": "house_number",
        "value": "475"
    },
    {
        "label": "road",
        "value": "sansome st"
    },
    {
        "label": "city",
        "value": "san francisco"
    },
    {
        "label": "state",
        "value": "ca"
    }
]

By default both Libpostal and the Libpostal API return results a list of dictionaries, each containing a label and value key. This is because there are occasions when a given key may have multiple values, for example an address that contains a cross-street.

If you would prefer to have API results returned as a simple dictionary with labels as keys and values as lists of possible strings you should append the format=keys parameter.

Example

curl -s -X GET 'https://libpostal.mapzen.com/parse?address=475+Sansome+St+San+Francisco+CA&format=keys' | python -mjson.tool
{
    "city": [
        "san francisco"
    ],
    "house_number": [
        "475"
    ],
    "road": [
        "sansome st"
    ],
    "state": [
        "ca"
    ]
}

The complete list of labels defined in Libpostal are:

  • house
  • house_number
  • road
  • suburb
  • city_district
  • city
  • state_district
  • state
  • postalcode
  • country

Depending on the address string you are parsing only some of those labels may be returned in the result set.

Usage limits

The Libpostal service requires a Mapzen API key. In a request, you must append your own API key to the URL, following api_key=. See the Mapzen developer overview for more on API keys and rate limits.