Guides

Parse a free-text address field into structured components

A single free-text address field is easy to collect and hard to work with afterward, especially once you need to filter by city or group by region. Forward geocoding does the parsing for you as a side effect of resolving the address to coordinates.

Sending the free text

GET /v1/forward?q=1600 Pennsylvania Avenue, Washington, DC 20500&limit=1
{
  "status": "ok",
  "query": "1600 Pennsylvania Avenue, Washington, DC 20500",
  "results": [
    {
      "formatted": "1600 Pennsylvania Avenue NW, Washington, DC 20500",
      "lat": 38.8977,
      "lon": -77.0365,
      "type": "address",
      "precision": "house",
      "confidence": 0.97,
      "place_id": "def456",
      "components": {"house_number": "1600", "street": "Pennsylvania Avenue NW", "city": "Washington", "region": "DC", "postcode": "20500", "country": "US"}
    }
  ]
}

Storing components separately

Once you have the components object, write each field into its own database column rather than keeping only the original free-text string. This makes it possible to filter customer records by city or region, generate accurate regional reports, and validate that a postal code and city actually belong together, none of which is practical against a single unstructured string.

A second example: an address in a different format

Address structure is not the same everywhere. A United Kingdom address might resolve with a county in place of a US-style region, and a component like house_number might be entirely absent for a named building. Sending the same style of request works regardless of country, but the component keys you actually get back can vary, so build your storage schema to tolerate a component being missing rather than assuming every country fills in the exact same set every time.

A common mistake to avoid

Do not hard-code an assumption that every result will contain all of house_number, street, city, region, and postcode, then treat any address missing one of them as a parsing error. A perfectly valid address, especially outside a house-numbered urban grid, can legitimately come back with some fields empty. Building strict validation around a full set of components will reject real customer input that the endpoint parsed correctly.

Keeping the original text too

Store the original free-text input alongside the parsed components rather than discarding it. If a component comes back incomplete or a customer needs to correct something later, having the original text on hand makes re-parsing or manual correction straightforward.

Handling partial parses

Not every address resolves with every component filled in. A rural address might come back without a house_number, and a small town might come back without a distinct region value. Treat missing component fields as legitimately empty rather than as a parsing failure, and fall back to the formatted string for display when a specific component you wanted is not present.

Handling more than one plausible match

Raising limit above 1 returns several candidate results ordered by how well each matches the free text, which is useful when you want to show the customer a short pick list rather than silently committing to the top match. This is a reasonable middle ground between full automatic parsing and a fully manual entry form, particularly for addresses your confidence threshold would otherwise flag as uncertain.

What it costs

Parsing a free-text field this way costs one request per address, the same as any other forward geocoding lookup. A backfill job cleaning up an existing table of free-text addresses can run through the whole table as a bulk request, one request per row.

Turning free text into structured fields is a natural side effect of geocoding an address, not an extra step. The forward geocoding docs list every component the endpoint can return.