Converting Addresses into GPS Coordinates with a Geocoding API

Whenever your application collects an address from a user, sooner or later you need to know where that address actually is: to show it on a map, compute a delivery route, find the nearest store, or check that the address exists at all. The process of turning a human-readable address like 221B Baker Street, London into geographic coordinates (a latitude and a longitude) is called geocoding, and in this article we'll implement it in Node.js.

We'll look at two options: the Google Maps Geocoding API, and an affordable alternative using ExoAPI. We'll finish with a real-world task: geocoding a whole CSV file of addresses in one go.

How Geocoding Works

A geocoding service keeps a giant, indexed database of addresses and their coordinates. You send it a free-text address, it parses the text into components (street, house number, city, country), finds the best match, and returns:

  • the latitude and longitude of the address
  • the normalized address, split into structured components

That second part is more useful than it sounds: because the response is normalized, geocoding doubles as address validation and cleaning. Send "221B Baker Street, London, United Kingdom" and the API comes back with "221B Baker Street, London NW1 6XE, United Kingdom" - the postal code filled in and every component split out.

One practical tip before we start: include the country whenever you know it. Free-text place names are ambiguous - there is a Baker Street in London, United Kingdom, and another one in London, Ontario, Canada - and the country (or the locale parameter) is what lets the geocoder pick the right one.

Option A - Using the Google Maps Geocoding API

1. Get an API Key

Go to the Google Cloud Console, create a project, enable the "Geocoding API" and generate an API key. Note that Google requires a billing account with a credit card even for the free tier.

2. Geocode an Address

The Geocoding API is a simple GET endpoint:

const API_KEY = "<your-google-api-key>";

async function geocode(address) {
  const res = await fetch(`https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(address)}&key=${API_KEY}`);
  const data = await res.json();

  if (data.status !== "OK") {
    throw new Error(`Geocoding failed: ${data.status}`);
  }

  const result = data.results[0];
  return {
    lat: result.geometry.location.lat,
    lon: result.geometry.location.lng,
    address: result.formatted_address,
  };
}

console.log(await geocode("221B Baker Street, London"));
// { lat: 51.523767, lon: -0.1585557, address: '221B Baker St, London NW1 6XE, UK' }

This works well, but there are two constraints to be aware of:

  1. Pricing is per request. Every 1,000 geocoding requests are billed, so costs grow linearly with your traffic and are hard to predict.
  2. The terms of service restrict what you can do with the results. Storing or caching Google geocoding results in your own database is generally not allowed, which rules out the most effective cost optimization: geocode once, reuse forever.

Option B - Using ExoAPI

ExoAPI's geocoding API is powered by regularly updated OpenStreetMap data, and is priced as a flat monthly subscription: from 9€/month for 1,000 requests per day, with every other ExoAPI API included. You can also store and reuse the results freely in your own database.

1. Get an API Key

Create an account at exoapi.dev (14-day free trial, no credit card required) and copy your API key from the dashboard.

2. Geocode an Address

Using the official SDK:

npm install @flower-digital/exoapi-sdk
import { ExoAPI } from "@flower-digital/exoapi-sdk";

const exoapi = new ExoAPI({ apiKey: "<your-api-key>" });

const res = await exoapi.geocoding({
  address: "221B Baker Street, London, United Kingdom",
  locale: "en-GB",
});
console.log(res);

The response contains the coordinates plus the full set of structured address components:

{
  "address": "221B Baker Street, London NW1 6XE, United Kingdom",
  "lat": 51.5237498111111,
  "lon": -0.1585443,
  "houseNumber": "221B",
  "street": "Baker Street",
  "postalCode": "NW1 6XE",
  "city": "London",
  "region": "England",
  "regionCode": "GB-ENG",
  "country": "United Kingdom",
  "countryCode": "GB",
  "countryCode3": "GBR",
  "currency": "GBP"
}

If you prefer plain HTTP, the same call is a single POST request:

const res = await fetch("https://api.exoapi.dev/geocoding", {
  method: "POST",
  headers: {
    Authorization: "Bearer <your-api-key>",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ address: "221B Baker Street, London, United Kingdom" }),
});
console.log(await res.json());

The optional locale parameter (a BCP 47 code like en-GB, fr-FR or pt-BR) localizes the returned address components.

Geocoding a CSV File in Bulk

A very common real-world task: you have a spreadsheet of customer or store addresses and need coordinates for all of them. Here is a small Node.js script that reads addresses.csv (one address per line - remember to include the country), geocodes each address, and writes addresses-geocoded.csv:

import { ExoAPI } from "@flower-digital/exoapi-sdk";
import fs from "fs";

const exoapi = new ExoAPI({ apiKey: "<your-api-key>" });

const lines = fs
  .readFileSync("addresses.csv", "utf-8")
  .split("\n")
  .filter((line) => line.trim() !== "");

const output = ["address,lat,lon,postalCode,city,country"];

for (const line of lines) {
  try {
    const res = await exoapi.geocoding({ address: line });
    output.push([res.address, res.lat, res.lon, res.postalCode, res.city, res.country].map((value) => `"${value ?? ""}"`).join(","));
    console.log(`✅ ${line} -> ${res.lat}, ${res.lon}`);
  } catch (err) {
    output.push(`"${line}",,,,,`);
    console.error(`❌ ${line}`, err);
  }
}

fs.writeFileSync("addresses-geocoded.csv", output.join("\n"));

Because ExoAPI lets you store the results, you only ever pay to geocode an address once - after that, the coordinates live in your own database. With the Starter plan's 1,000 requests per day you can geocode a 30,000-row file over a month for 9€, and larger plans go up to 50,000 requests per day.

Conclusion

Geocoding turns the addresses your application already collects into coordinates you can compute with, and a geocoding API gives you that power in a single HTTP call. Choose Google Maps if you're already invested in their platform, or ExoAPI if you want predictable pricing, structured address components, and the freedom to keep the results. Happy geocoding! 🌍📍


Get started building.

Sign up today and get access to our platform's easy-to-use APIs, all with just one subscription
No credit card required