Geocoding, IP and timezone lookups over one plain HTTP API
Turn addresses into coordinates and back, find out where an IPv4 or IPv6 address sits, get the timezone or elevation of any point, and resolve postal codes. Send a GET request, read the JSON. Nothing to install.
Try it before you buy anything: 2,500 requests a day are always free, with no API key and no account. Need more? Sign up with an email address, nothing else, and add credits at $0.001 per request, or go Unlimited for €50 a month. Cards and crypto accepted.
$ curl "https://api.mygeocode.com/v1/reverse?lat=48.8584&lon=2.2945"{ "status": "ok", "result": { "formatted": "5 Avenue Anatole France, 75007 Paris, France", "lat": 48.85837, "lon": 2.29448, "distance_m": 12, "precision": "house", "components": { "house_number": "5", "road": "Avenue Anatole France", "city": "Paris", "postcode": "75007", "country": "France", "country_code": "fr" } } }
Eight lookups, one base URL
Every endpoint lives under https://api.mygeocode.com/v1/, takes query parameters, and returns JSON with the same envelope. Learn one and you know them all.
Forward Geocoding API
GET /v1/forwardSend an address, a place name or a rough description and get coordinates, a cleaned up address and each of its parts.
Details and examplesReverse Geocoding API
GET /v1/reverseSend a latitude and longitude and get the nearest address, with the city, region, postcode and country broken out.
Details and examplesAddress Autocomplete API
GET /v1/autocompleteSuggest addresses while someone types. Every suggestion comes with coordinates, so you rarely need a second call.
Details and examplesIPv4 Lookup API
GET /v1/ipv4Country, region, city, coordinates, timezone and network owner for any IPv4 address, or for the caller if you leave it out.
Details and examplesIPv6 Lookup API
GET /v1/ipv6The same details for IPv6 addresses, plus the announced prefix the address belongs to.
Details and examplesTimezone Lookup API
GET /v1/timezoneIANA timezone name, UTC offset, DST status and local time for any coordinate, now or at a timestamp you choose.
Details and examplesElevation Lookup API
GET /v1/elevationHeight above sea level in metres for one point, or up to 100 points in a single call.
Details and examplesPostal Code Lookup API
GET /v1/postcodeTurn a postal code into a place name, region and coordinates. Works for ZIP codes, postcodes and their equivalents in most countries.
Details and examplesEvery result says how precise it is
A geocoder that returns a city centre when you asked for a house number is worse than one that says it could not find the house. Each result we return carries a precision field with one of four values, so your code can decide what to do with a coarse match instead of guessing.
Coverage is not the same everywhere, and we would rather show you than make a blanket claim. The coverage page lists the best level we reach in each of 249 countries and territories.
| Level | What the point represents |
|---|---|
house | The building or parcel itself. The point sits on the property. |
street | A position along the street, interpolated from the house number range of that block. |
postcode | The centre of the postal code area. |
admin | The centre of the city, district, region or country, whichever is the most specific match we could make. |
Already using someone else's API? Change the hostname.
We run drop-in hosts that accept the same paths and parameters as Google Maps, Bing Maps, HERE, Mapbox, Geocode.Farm, Nominatim and eleven others, and answer in their response format with our data. Your parsing code does not change. Put your My Geocode key where the old key went, or leave it out for the free tier.
$ curl "https://maps.googleapis.com/maps/api/geocode/json?address=10+Downing+St+London&key=GOOGLE_KEY"$ curl "https://gapi.mygeocode.com/maps/api/geocode/json?address=10+Downing+St+London&key=MYGEOCODE_KEY"The same idea works for JavaScript libraries. Load the Google Maps JavaScript API from gapi.mygeocode.com and google.maps.Map, Geocoder and Places Autocomplete keep working, with map loads that cost nothing. There are loaders for the Bing Maps V8 control, HERE Maps for JavaScript and MapQuest.js, and settings for MapLibre, Mapbox GL and Leaflet geocoder plugins.
- Google Maps
- Bing Maps
- HERE
- Mapbox
- Geocode.Farm
- Nominatim
- OpenCage
- LocationIQ
- Geoapify
- TomTom
- MapQuest
- Geocodio
- PositionStack
- ip-api
- ipinfo
- ipstack
- Open-Elevation
If it can send an HTTP request, it can use this
No SDK is needed. These examples geocode an address and print its coordinates. Official libraries for each language are on the way and will stay thin wrappers around these same calls.
$ curl "https://api.mygeocode.com/v1/forward?q=221B+Baker+Street,+London"
# With a key, once you have one
$ curl -H "X-API-Key: YOUR_KEY" "https://api.mygeocode.com/v1/forward?q=221B+Baker+Street,+London"const url = new URL("https://api.mygeocode.com/v1/forward");
url.searchParams.set("q", "221B Baker Street, London");
const res = await fetch(url, { headers: { "X-API-Key": process.env.MYGEOCODE_KEY } });
const data = await res.json();
const [first] = data.results;
console.log(first.lat, first.lon, first.precision);import os
import requests
r = requests.get(
"https://api.mygeocode.com/v1/forward",
params={"q": "221B Baker Street, London"},
headers={"X-API-Key": os.environ["MYGEOCODE_KEY"]},
timeout=10,
)
r.raise_for_status()
first = r.json()["results"][0]
print(first["lat"], first["lon"], first["precision"])<?php
$url = "https://api.mygeocode.com/v1/forward?" . http_build_query([
"q" => "221B Baker Street, London",
]);
$context = stream_context_create(["http" => ["header" => "X-API-Key: " . getenv("MYGEOCODE_KEY")]]);
$data = json_decode(file_get_contents($url, false, $context), true);
$first = $data["results"][0];
echo $first["lat"], ", ", $first["lon"], " (", $first["precision"], ")\n";package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
)
func main() {
q := url.Values{"q": {"221B Baker Street, London"}}
req, _ := http.NewRequest("GET", "https://api.mygeocode.com/v1/forward?"+q.Encode(), nil)
req.Header.Set("X-API-Key", os.Getenv("MYGEOCODE_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var data struct {
Results []struct {
Lat float64 `json:"lat"`
Lon float64 `json:"lon"`
Precision string `json:"precision"`
} `json:"results"`
}
json.NewDecoder(resp.Body).Decode(&data)
fmt.Println(data.Results[0].Lat, data.Results[0].Lon, data.Results[0].Precision)
}import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
public class Geocode {
public static void main(String[] args) throws Exception {
String q = URLEncoder.encode("221B Baker Street, London", StandardCharsets.UTF_8);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.mygeocode.com/v1/forward?q=" + q))
.header("X-API-Key", System.getenv("MYGEOCODE_KEY"))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}using System.Net.Http;
using System.Text.Json;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", Environment.GetEnvironmentVariable("MYGEOCODE_KEY"));
var q = Uri.EscapeDataString("221B Baker Street, London");
var json = await client.GetStringAsync($"https://api.mygeocode.com/v1/forward?q={q}");
using var doc = JsonDocument.Parse(json);
var first = doc.RootElement.GetProperty("results")[0];
Console.WriteLine($"{first.GetProperty("lat")}, {first.GetProperty("lon")} ({first.GetProperty("precision")})");require "net/http"
require "json"
uri = URI("https://api.mygeocode.com/v1/forward")
uri.query = URI.encode_www_form(q: "221B Baker Street, London")
req = Net::HTTP::Get.new(uri)
req["X-API-Key"] = ENV["MYGEOCODE_KEY"]
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
first = JSON.parse(res.body)["results"][0]
puts "#{first["lat"]}, #{first["lon"]} (#{first["precision"]})"Start with nothing. Sign up with an email when you need more.
Usage is counted per IP address, so the free tier needs no key, no account and no card. Each IPv4 address gets 2,500 requests a day across all endpoints and drop-in hosts, measured from midnight UTC. IPv6 usage is counted per /40 block rather than per address, because one customer can hold billions of addresses and we would rather not let a single script eat the whole pool.
When you want more than that, an account takes an email address and nothing else. No name, no company, no card until you decide to add credits. Pay by card or in crypto.
-
Use it. No key, no account.
2,500 requests a day from each IPv4 address or IPv6 /40, on every endpoint. Enough to build the whole integration and run a small site.
-
Add credits when you need more
Sign up with an email, top up whenever you like, and credits are used only for requests above the free 2,500 a day, even when you use an API key. Whitelist your server IPs, or use a key, which works from up to two IP addresses per 24 hours.
-
Or go Unlimited
€50 a month, as many requests as you need, from up to two IP addresses per 24 hours per account.
Free to try, simple to pay for
Every endpoint costs the same. Every drop-in host counts the same. No tiers, no per-seat charges, no contract. Cards and crypto accepted.
Free, always
2,500 requests a day. No key, no account, no card. Counted per IPv4 address or IPv6 /40. Accounts get the same 2,500 a day before any credits are used.
Credits
$0.001 per request above the free 2,500 each day, taken from a balance you top up whenever you like. No monthly fee, no expiry. 10,000 requests in a day use $7.50 of credit.
Unlimited
€50 a month. As many requests as you need across every endpoint and every drop-in host, from up to two IP addresses per 24 hours per account.
Official libraries, one per language, all thin
We are writing small client libraries for JavaScript and TypeScript, Python, PHP, Go, Java, C#, Ruby and Rust. Each will give you typed responses, sensible timeouts, retries on 429 and 503, and nothing else. When one is ready it goes on the SDK page with its install command.
Do I need a key to try it?
No. Send a request from any machine and it counts toward that machine's 2,500 a day. The demo page does exactly that from your browser.
What happens at request 2,501?
Without an account you get HTTP 429 until midnight UTC. With an account and credits, the request goes through and uses one credit ($0.001). On the Unlimited plan, nothing changes.
Why is a key limited to two IPs?
Keys are meant for servers. Limiting a key to two addresses in any 24 hour window means a key that leaks into a public repository cannot be used from a hundred machines. On credits, whitelisting server addresses has no limit. On the Unlimited plan the two-address limit applies to the whole account.
Can I store the results?
Yes. Cache them, save them in your database, show them on a map from another provider. The terms only ask that you do not resell the raw data as a geocoding service of your own.
Send your first request now
The demo sends live requests from your browser and opens the JSON response. No account, no key, no card. When you outgrow 2,500 a day, signing up takes an email address and nothing more.